diff options
author | Bruce Momjian | 2000-04-12 17:17:23 +0000 |
---|---|---|
committer | Bruce Momjian | 2000-04-12 17:17:23 +0000 |
commit | 52f77df613cea1803ce86321c37229626d9f213c (patch) | |
tree | bd9ac9f667f295cb65f4c448a5bb5a062d656b27 /src | |
parent | db4518729d85da83eafdacbcebaeb12618517595 (diff) |
Ye-old pgindent run. Same 4-space tabs.
Diffstat (limited to 'src')
418 files changed, 23531 insertions, 20144 deletions
diff --git a/src/backend/access/common/heaptuple.c b/src/backend/access/common/heaptuple.c index 4eec6ed6d07..d30e4c7fe64 100644 --- a/src/backend/access/common/heaptuple.c +++ b/src/backend/access/common/heaptuple.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.61 2000/01/26 05:55:53 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.62 2000/04/12 17:14:36 momjian Exp $ * * NOTES * The old interface functions have been converted to macros @@ -137,9 +137,9 @@ DataFill(char *data, *((int32 *) value[i])); break; default: - Assert(att[i]->attlen >= 0); - memmove(data, DatumGetPointer(value[i]), - (size_t)(att[i]->attlen)); + Assert(att[i]->attlen >= 0); + memmove(data, DatumGetPointer(value[i]), + (size_t) (att[i]->attlen)); break; } data = (char *) att_addlength((long) data, att[i]->attlen, value[i]); @@ -326,7 +326,7 @@ nocachegetattr(HeapTuple tuple, Form_pg_attribute *att = tupleDesc->attrs; int slow = 0; /* do we have to walk nulls? */ - (void)isnull; /*not used*/ + (void) isnull; /* not used */ #ifdef IN_MACRO /* This is handled in the macro */ Assert(attnum > 0); @@ -681,7 +681,7 @@ heap_formtuple(TupleDesc tupleDescriptor, len += bitmaplen; } - hoff = len = MAXALIGN(len); /* be conservative here */ + hoff = len = MAXALIGN(len); /* be conservative here */ len += ComputeDataSize(tupleDescriptor, value, nulls); @@ -806,11 +806,9 @@ void heap_freetuple(HeapTuple htup) { if (htup->t_data != NULL) - if (htup->t_datamcxt != NULL && (char *)(htup->t_data) != - ((char *) htup + HEAPTUPLESIZE)) - { + if (htup->t_datamcxt != NULL && (char *) (htup->t_data) != + ((char *) htup + HEAPTUPLESIZE)) elog(NOTICE, "TELL Jan Wieck: heap_freetuple() found separate t_data"); - } pfree(htup); } @@ -835,7 +833,7 @@ heap_addheader(uint32 natts, /* max domain index */ len = offsetof(HeapTupleHeaderData, t_bits); - hoff = len = MAXALIGN(len); /* be conservative */ + hoff = len = MAXALIGN(len); /* be conservative */ len += structlen; tuple = (HeapTuple) palloc(HEAPTUPLESIZE + len); tuple->t_datamcxt = CurrentMemoryContext; @@ -850,8 +848,8 @@ heap_addheader(uint32 natts, /* max domain index */ td->t_infomask = 0; td->t_infomask |= HEAP_XMAX_INVALID; - if (structlen > 0) - memmove((char *) td + hoff, structure, (size_t)structlen); + if (structlen > 0) + memmove((char *) td + hoff, structure, (size_t) structlen); return tuple; } diff --git a/src/backend/access/common/indextuple.c b/src/backend/access/common/indextuple.c index 438318747d2..e11ddbc1dc9 100644 --- a/src/backend/access/common/indextuple.c +++ b/src/backend/access/common/indextuple.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/common/indextuple.c,v 1.42 2000/01/26 05:55:53 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/common/indextuple.c,v 1.43 2000/04/12 17:14:37 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -60,7 +60,7 @@ index_formtuple(TupleDesc tupleDescriptor, hoff = IndexInfoFindDataOffset(infomask); size = hoff + ComputeDataSize(tupleDescriptor, value, null); - size = MAXALIGN(size); /* be conservative */ + size = MAXALIGN(size); /* be conservative */ tp = (char *) palloc(size); tuple = (IndexTuple) tp; @@ -134,7 +134,7 @@ nocache_index_getattr(IndexTuple tup, int data_off; /* tuple data offset */ Form_pg_attribute *att = tupleDesc->attrs; - (void)isnull; + (void) isnull; /* ---------------- * sanity checks * ---------------- diff --git a/src/backend/access/common/tupdesc.c b/src/backend/access/common/tupdesc.c index b2af4ff932e..1e8d2ae0034 100644 --- a/src/backend/access/common/tupdesc.c +++ b/src/backend/access/common/tupdesc.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.61 2000/01/31 04:35:48 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.62 2000/04/12 17:14:37 momjian Exp $ * * NOTES * some of the executor utility code such as "ExecTypeFromTL" should be @@ -229,17 +229,19 @@ FreeTupleDesc(TupleDesc tupdesc) bool equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2) { - int i; + int i; if (tupdesc1->natts != tupdesc2->natts) return false; for (i = 0; i < tupdesc1->natts; i++) { - Form_pg_attribute attr1 = tupdesc1->attrs[i]; - Form_pg_attribute attr2 = tupdesc2->attrs[i]; + Form_pg_attribute attr1 = tupdesc1->attrs[i]; + Form_pg_attribute attr2 = tupdesc2->attrs[i]; - /* We do not need to check every single field here, and in fact - * some fields such as attdisbursion probably shouldn't be compared. + /* + * We do not need to check every single field here, and in fact + * some fields such as attdisbursion probably shouldn't be + * compared. */ if (strcmp(NameStr(attr1->attname), NameStr(attr2->attname)) != 0) return false; @@ -254,8 +256,8 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2) } if (tupdesc1->constr != NULL) { - TupleConstr *constr1 = tupdesc1->constr; - TupleConstr *constr2 = tupdesc2->constr; + TupleConstr *constr1 = tupdesc1->constr; + TupleConstr *constr2 = tupdesc2->constr; if (constr2 == NULL) return false; @@ -263,8 +265,8 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2) return false; for (i = 0; i < (int) constr1->num_defval; i++) { - AttrDefault *defval1 = constr1->defval + i; - AttrDefault *defval2 = constr2->defval + i; + AttrDefault *defval1 = constr1->defval + i; + AttrDefault *defval2 = constr2->defval + i; if (defval1->adnum != defval2->adnum) return false; @@ -275,8 +277,8 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2) return false; for (i = 0; i < (int) constr1->num_check; i++) { - ConstrCheck *check1 = constr1->check + i; - ConstrCheck *check2 = constr2->check + i; + ConstrCheck *check1 = constr1->check + i; + ConstrCheck *check2 = constr2->check + i; if (strcmp(check1->ccname, check2->ccname) != 0) return false; @@ -585,8 +587,9 @@ BuildDescForRelation(List *schema, char *relname) constr->has_not_null = true; desc->attrs[attnum - 1]->attnotnull = entry->is_not_null; - /* Note we copy only pre-cooked default expressions. - * Digestion of raw ones is someone else's problem. + /* + * Note we copy only pre-cooked default expressions. Digestion of + * raw ones is someone else's problem. */ if (entry->cooked_default != NULL) { diff --git a/src/backend/access/gist/gist.c b/src/backend/access/gist/gist.c index 9e93f1d652d..66a3702e438 100644 --- a/src/backend/access/gist/gist.c +++ b/src/backend/access/gist/gist.c @@ -6,7 +6,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.52 2000/03/17 02:36:00 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.53 2000/04/12 17:14:39 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -52,8 +52,10 @@ void gistdelete(Relation r, ItemPointer tid); static IndexTuple gist_tuple_replacekey(Relation r, GISTENTRY entry, IndexTuple t); static void gistcentryinit(GISTSTATE *giststate, GISTENTRY *e, char *pr, Relation r, Page pg, OffsetNumber o, int b, bool l); + #ifdef GISTDEBUG static char *int_range_out(INTRANGE *r); + #endif /* @@ -98,7 +100,7 @@ gistbuild(Relation heap, /* no locking is needed */ - CommandCounterIncrement(); /* so we can see the new pg_index tuple */ + CommandCounterIncrement(); /* so we can see the new pg_index tuple */ initGISTstate(&giststate, index); @@ -186,7 +188,7 @@ gistbuild(Relation heap, #ifndef OMIT_PARTIAL_INDEX /* SetSlotContents(slot, htup); */ slot->val = htup; - if (! ExecQual((List *) pred, econtext, false)) + if (!ExecQual((List *) pred, econtext, false)) continue; #endif /* OMIT_PARTIAL_INDEX */ } @@ -272,18 +274,18 @@ gistbuild(Relation heap, /* * Since we just counted the tuples in the heap, we update its stats * in pg_class to guarantee that the planner takes advantage of the - * index we just created. But, only update statistics during - * normal index definitions, not for indices on system catalogs - * created during bootstrap processing. We must close the relations - * before updating statistics to guarantee that the relcache entries - * are flushed when we increment the command counter in UpdateStats(). - * But we do not release any locks on the relations; those will be - * held until end of transaction. + * index we just created. But, only update statistics during normal + * index definitions, not for indices on system catalogs created + * during bootstrap processing. We must close the relations before + * updating statistics to guarantee that the relcache entries are + * flushed when we increment the command counter in UpdateStats(). But + * we do not release any locks on the relations; those will be held + * until end of transaction. */ if (IsNormalProcessingMode()) { - Oid hrelid = RelationGetRelid(heap); - Oid irelid = RelationGetRelid(index); + Oid hrelid = RelationGetRelid(heap); + Oid irelid = RelationGetRelid(index); bool inplace = IsReindexProcessing(); heap_close(heap, NoLock); diff --git a/src/backend/access/gist/gistscan.c b/src/backend/access/gist/gistscan.c index a7d1faf43db..2196e897e4a 100644 --- a/src/backend/access/gist/gistscan.c +++ b/src/backend/access/gist/gistscan.c @@ -266,7 +266,7 @@ gistdropscan(IndexScanDesc s) prev = l; if (l == (GISTScanList) NULL) - elog(ERROR, "GiST scan list corrupted -- cannot find 0x%p", (void*)s); + elog(ERROR, "GiST scan list corrupted -- cannot find 0x%p", (void *) s); if (prev == (GISTScanList) NULL) GISTScans = l->gsl_next; diff --git a/src/backend/access/hash/hash.c b/src/backend/access/hash/hash.c index d116aa1a499..1e5bc15bf2f 100644 --- a/src/backend/access/hash/hash.c +++ b/src/backend/access/hash/hash.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/hash/hash.c,v 1.36 2000/03/01 05:39:22 inoue Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/hash/hash.c,v 1.37 2000/04/12 17:14:43 momjian Exp $ * * NOTES * This file contains only the public interface routines. @@ -149,7 +149,7 @@ hashbuild(Relation heap, #ifndef OMIT_PARTIAL_INDEX /* SetSlotContents(slot, htup); */ slot->val = htup; - if (! ExecQual((List *) pred, econtext, false)) + if (!ExecQual((List *) pred, econtext, false)) continue; #endif /* OMIT_PARTIAL_INDEX */ } @@ -230,18 +230,18 @@ hashbuild(Relation heap, /* * Since we just counted the tuples in the heap, we update its stats * in pg_class to guarantee that the planner takes advantage of the - * index we just created. But, only update statistics during - * normal index definitions, not for indices on system catalogs - * created during bootstrap processing. We must close the relations - * before updating statistics to guarantee that the relcache entries - * are flushed when we increment the command counter in UpdateStats(). - * But we do not release any locks on the relations; those will be - * held until end of transaction. + * index we just created. But, only update statistics during normal + * index definitions, not for indices on system catalogs created + * during bootstrap processing. We must close the relations before + * updating statistics to guarantee that the relcache entries are + * flushed when we increment the command counter in UpdateStats(). But + * we do not release any locks on the relations; those will be held + * until end of transaction. */ if (IsNormalProcessingMode()) { - Oid hrelid = RelationGetRelid(heap); - Oid irelid = RelationGetRelid(index); + Oid hrelid = RelationGetRelid(heap); + Oid irelid = RelationGetRelid(index); bool inplace = IsReindexProcessing(); heap_close(heap, NoLock); diff --git a/src/backend/access/hash/hashfunc.c b/src/backend/access/hash/hashfunc.c index 78af6353f0b..80d9ac3741c 100644 --- a/src/backend/access/hash/hashfunc.c +++ b/src/backend/access/hash/hashfunc.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/hash/hashfunc.c,v 1.24 2000/02/21 03:36:46 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/hash/hashfunc.c,v 1.25 2000/04/12 17:14:44 momjian Exp $ * * NOTES * These functions are stored in pg_amproc. For each operator class @@ -146,14 +146,14 @@ hashoidvector(Oid *key) int i; uint32 result = 0; - for (i = INDEX_MAX_KEYS; --i >= 0; ) + for (i = INDEX_MAX_KEYS; --i >= 0;) result = (result << 1) ^ (~(uint32) key[i]); return result; } /* * Note: hashint2vector currently can't be used as a user hash table - * hash function, because it has no pg_proc entry. We only need it + * hash function, because it has no pg_proc entry. We only need it * for catcache indexing. */ uint32 @@ -162,7 +162,7 @@ hashint2vector(int16 *key) int i; uint32 result = 0; - for (i = INDEX_MAX_KEYS; --i >= 0; ) + for (i = INDEX_MAX_KEYS; --i >= 0;) result = (result << 1) ^ (~(uint32) key[i]); return result; } diff --git a/src/backend/access/hash/hashscan.c b/src/backend/access/hash/hashscan.c index d44ba69b9bd..979baf8d70c 100644 --- a/src/backend/access/hash/hashscan.c +++ b/src/backend/access/hash/hashscan.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/hash/hashscan.c,v 1.22 2000/01/26 05:55:55 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/hash/hashscan.c,v 1.23 2000/04/12 17:14:44 momjian Exp $ * * NOTES * Because we can be doing an index scan on a relation while we @@ -75,7 +75,7 @@ _hash_dropscan(IndexScanDesc scan) last = chk; if (chk == (HashScanList) NULL) - elog(ERROR, "hash scan list trashed; can't find 0x%p", (void*)scan); + elog(ERROR, "hash scan list trashed; can't find 0x%p", (void *) scan); if (last == (HashScanList) NULL) HashScans = chk->hashsl_next; diff --git a/src/backend/access/hash/hashsearch.c b/src/backend/access/hash/hashsearch.c index d6ae498d19d..21f45f47137 100644 --- a/src/backend/access/hash/hashsearch.c +++ b/src/backend/access/hash/hashsearch.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/hash/hashsearch.c,v 1.23 2000/03/17 02:36:02 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/hash/hashsearch.c,v 1.24 2000/04/12 17:14:44 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -351,7 +351,7 @@ _hash_step(IndexScanDesc scan, Buffer *bufP, ScanDirection dir, Buffer metabuf) opaque = (HashPageOpaque) PageGetSpecialPointer(page); Assert(opaque->hasho_bucket == bucket); while (PageIsEmpty(page) && - BlockNumberIsValid(opaque->hasho_nextblkno)) + BlockNumberIsValid(opaque->hasho_nextblkno)) _hash_readnext(rel, &buf, &page, &opaque); maxoff = PageGetMaxOffsetNumber(page); offnum = FirstOffsetNumber; diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d51705fa472..29d6c9e0f9e 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.66 2000/02/09 03:49:47 inoue Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.67 2000/04/12 17:14:45 momjian Exp $ * * * INTERFACE ROUTINES @@ -23,7 +23,7 @@ * heap_fetch - retrive tuple with tid * heap_insert - insert tuple into a relation * heap_delete - delete a tuple from a relation - * heap_update - replace a tuple in a relation with another tuple + * heap_update - replace a tuple in a relation with another tuple * heap_markpos - mark scan position * heap_restrpos - restore position to marked location * @@ -120,9 +120,9 @@ initscan(HeapScanDesc scan, * ---------------- */ scan->rs_ntup.t_datamcxt = scan->rs_ctup.t_datamcxt = - scan->rs_ptup.t_datamcxt = NULL; + scan->rs_ptup.t_datamcxt = NULL; scan->rs_ntup.t_data = scan->rs_ctup.t_data = - scan->rs_ptup.t_data = NULL; + scan->rs_ptup.t_data = NULL; scan->rs_nbuf = scan->rs_cbuf = scan->rs_pbuf = InvalidBuffer; } else if (atend) @@ -188,8 +188,9 @@ unpinscan(HeapScanDesc scan) if (BufferIsValid(scan->rs_nbuf)) ReleaseBuffer(scan->rs_nbuf); - /* we don't bother to clear rs_pbuf etc --- caller must - * reinitialize them if scan descriptor is not being deleted. + /* + * we don't bother to clear rs_pbuf etc --- caller must reinitialize + * them if scan descriptor is not being deleted. */ } @@ -544,7 +545,7 @@ heap_open(Oid relationId, LOCKMODE lockmode) if (lockmode == NoLock) return r; /* caller must check RelationIsValid! */ - if (! RelationIsValid(r)) + if (!RelationIsValid(r)) elog(ERROR, "Relation %u does not exist", relationId); LockRelation(r, lockmode); @@ -586,7 +587,7 @@ heap_openr(const char *relationName, LOCKMODE lockmode) if (lockmode == NoLock) return r; /* caller must check RelationIsValid! */ - if (! RelationIsValid(r)) + if (!RelationIsValid(r)) elog(ERROR, "Relation '%s' does not exist", relationName); LockRelation(r, lockmode); @@ -646,7 +647,7 @@ heap_beginscan(Relation relation, * sanity checks * ---------------- */ - if (! RelationIsValid(relation)) + if (!RelationIsValid(relation)) elog(ERROR, "heap_beginscan: !RelationIsValid(relation)"); /* ---------------- @@ -659,7 +660,7 @@ heap_beginscan(Relation relation, * Acquire AccessShareLock for the duration of the scan * * Note: we could get an SI inval message here and consequently have - * to rebuild the relcache entry. The refcount increment above + * to rebuild the relcache entry. The refcount increment above * ensures that we will rebuild it and not just flush it... * ---------------- */ @@ -681,6 +682,7 @@ heap_beginscan(Relation relation, scan->rs_nkeys = (short) nkeys; if (nkeys) + /* * we do this here instead of in initscan() because heap_rescan * also calls initscan() and we don't want to allocate memory @@ -847,9 +849,7 @@ heap_getnext(HeapScanDesc scandesc, int backw) if (scan->rs_ptup.t_data == scan->rs_ctup.t_data && BufferIsInvalid(scan->rs_pbuf)) - { return NULL; - } /* * Copy the "current" tuple/buffer to "next". Pin/unpin the @@ -1095,8 +1095,10 @@ heap_fetch(Relation relation, } else { - /* All checks passed, so return the tuple as valid. - * Caller is now responsible for releasing the buffer. + + /* + * All checks passed, so return the tuple as valid. Caller is now + * responsible for releasing the buffer. */ *userbuf = buffer; } @@ -1109,17 +1111,18 @@ heap_fetch(Relation relation, */ ItemPointer heap_get_latest_tid(Relation relation, - Snapshot snapshot, - ItemPointer tid) + Snapshot snapshot, + ItemPointer tid) { ItemId lp = NULL; Buffer buffer; PageHeader dp; - OffsetNumber offnum; - HeapTupleData tp; - HeapTupleHeader t_data; - ItemPointerData ctid; - bool invalidBlock,linkend; + OffsetNumber offnum; + HeapTupleData tp; + HeapTupleHeader t_data; + ItemPointerData ctid; + bool invalidBlock, + linkend; /* ---------------- * get the buffer from the relation descriptor @@ -1149,11 +1152,11 @@ heap_get_latest_tid(Relation relation, invalidBlock = false; } if (invalidBlock) - { + { LockBuffer(buffer, BUFFER_LOCK_UNLOCK); ReleaseBuffer(buffer); return NULL; - } + } /* ---------------- * more sanity checks @@ -1175,7 +1178,7 @@ heap_get_latest_tid(Relation relation, snapshot, 0, (ScanKey) NULL); linkend = true; - if ((t_data->t_infomask & HEAP_XMAX_COMMITTED) && + if ((t_data->t_infomask & HEAP_XMAX_COMMITTED) && !ItemPointerEquals(tid, &ctid)) linkend = false; @@ -1186,7 +1189,7 @@ heap_get_latest_tid(Relation relation, { if (linkend) return NULL; - return heap_get_latest_tid(relation, snapshot, &ctid); + return heap_get_latest_tid(relation, snapshot, &ctid); } return tid; @@ -1300,10 +1303,11 @@ l1: LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE); if (TransactionIdDidAbort(xwait)) goto l1; - /* - * xwait is committed but if xwait had just marked - * the tuple for update then some other xaction could - * update this tuple before we got to this point. + + /* + * xwait is committed but if xwait had just marked the tuple for + * update then some other xaction could update this tuple before + * we got to this point. */ if (tp.t_data->t_xmax != xwait) goto l1; @@ -1345,11 +1349,11 @@ l1: } /* - * heap_update - replace a tuple + * heap_update - replace a tuple */ int heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, - ItemPointer ctid) + ItemPointer ctid) { ItemId lp; HeapTupleData oldtup; @@ -1396,10 +1400,11 @@ l2: LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE); if (TransactionIdDidAbort(xwait)) goto l2; - /* - * xwait is committed but if xwait had just marked - * the tuple for update then some other xaction could - * update this tuple before we got to this point. + + /* + * xwait is committed but if xwait had just marked the tuple for + * update then some other xaction could update this tuple before + * we got to this point. */ if (oldtup.t_data->t_xmax != xwait) goto l2; @@ -1521,10 +1526,11 @@ l3: LockBuffer(*buffer, BUFFER_LOCK_EXCLUSIVE); if (TransactionIdDidAbort(xwait)) goto l3; - /* - * xwait is committed but if xwait had just marked - * the tuple for update then some other xaction could - * update this tuple before we got to this point. + + /* + * xwait is committed but if xwait had just marked the tuple for + * update then some other xaction could update this tuple before + * we got to this point. */ if (tuple->t_data->t_xmax != xwait) goto l3; diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index b269ca90170..3fc2a69df1a 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Id: hio.c,v 1.30 2000/03/17 02:36:02 tgl Exp $ + * $Id: hio.c,v 1.31 2000/04/12 17:14:45 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -51,7 +51,7 @@ RelationPutHeapTuple(Relation relation, IncrHeapAccessStat(global_RelationPutHeapTuple); pageHeader = (Page) BufferGetPage(buffer); - len = MAXALIGN(tuple->t_len); /* be conservative */ + len = MAXALIGN(tuple->t_len); /* be conservative */ Assert(len <= PageGetFreeSpace(pageHeader)); offnum = PageAddItem((Page) pageHeader, (Item) tuple->t_data, @@ -108,11 +108,11 @@ RelationPutHeapTupleAtEnd(Relation relation, HeapTuple tuple) ItemId itemId; Item item; - len = MAXALIGN(tuple->t_len); /* be conservative */ + len = MAXALIGN(tuple->t_len); /* be conservative */ /* - * If we're gonna fail for oversize tuple, do it right away... - * this code should go away eventually. + * If we're gonna fail for oversize tuple, do it right away... this + * code should go away eventually. */ if (len > MaxTupleSize) elog(ERROR, "Tuple is too big: size %u, max size %ld", @@ -136,8 +136,8 @@ RelationPutHeapTupleAtEnd(Relation relation, HeapTuple tuple) lastblock = RelationGetNumberOfBlocks(relation); /* - * Get the last existing page --- may need to create the first one - * if this is a virgin relation. + * Get the last existing page --- may need to create the first one if + * this is a virgin relation. */ if (lastblock == 0) { @@ -168,12 +168,14 @@ RelationPutHeapTupleAtEnd(Relation relation, HeapTuple tuple) if (len > PageGetFreeSpace(pageHeader)) { + /* - * BUG: by elog'ing here, we leave the new buffer locked and not - * marked dirty, which may result in an invalid page header - * being left on disk. But we should not get here given the - * test at the top of the routine, and the whole deal should - * go away when we implement tuple splitting anyway... + * BUG: by elog'ing here, we leave the new buffer locked and + * not marked dirty, which may result in an invalid page + * header being left on disk. But we should not get here + * given the test at the top of the routine, and the whole + * deal should go away when we implement tuple splitting + * anyway... */ elog(ERROR, "Tuple is too big: size %u", len); } diff --git a/src/backend/access/heap/tuptoaster.c b/src/backend/access/heap/tuptoaster.c index 9176521a5fc..3aadfb2cde0 100644 --- a/src/backend/access/heap/tuptoaster.c +++ b/src/backend/access/heap/tuptoaster.c @@ -2,13 +2,13 @@ * * tuptoaster.c * Support routines for external and compressed storage of - * variable size attributes. + * variable size attributes. * * Copyright (c) 2000, PostgreSQL Global Development Group * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/heap/tuptoaster.c,v 1.2 2000/01/20 21:50:59 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/heap/tuptoaster.c,v 1.3 2000/04/12 17:14:45 momjian Exp $ * * * INTERFACE ROUTINES @@ -30,17 +30,17 @@ #ifdef TUPLE_TOASTER_ACTIVE void -heap_tuple_toast_attrs (Relation rel, HeapTuple newtup, HeapTuple oldtup) +heap_tuple_toast_attrs(Relation rel, HeapTuple newtup, HeapTuple oldtup) { return; } -varattrib * -heap_tuple_untoast_attr (varattrib *attr) +varattrib * +heap_tuple_untoast_attr(varattrib * attr) { elog(ERROR, "heap_tuple_untoast_attr() called"); } -#endif /* TUPLE_TOASTER_ACTIVE */ +#endif /* TUPLE_TOASTER_ACTIVE */ diff --git a/src/backend/access/index/genam.c b/src/backend/access/index/genam.c index 1bd02f839ad..3530320637b 100644 --- a/src/backend/access/index/genam.c +++ b/src/backend/access/index/genam.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/index/genam.c,v 1.24 2000/03/14 23:52:01 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/index/genam.c,v 1.25 2000/04/12 17:14:47 momjian Exp $ * * NOTES * many of the old access method routines have been turned into @@ -62,7 +62,7 @@ * * At the end of a scan, the AM's endscan routine undoes the locking, * but does *not* call IndexScanEnd --- the higher-level index_endscan - * routine does that. (We can't do it in the AM because index_endscan + * routine does that. (We can't do it in the AM because index_endscan * still needs to touch the IndexScanDesc after calling the AM.) * * Because of this, the AM does not have a choice whether to call @@ -114,7 +114,10 @@ RelationGetIndexScan(Relation relation, ItemPointerSetInvalid(&scan->currentMarkData); ItemPointerSetInvalid(&scan->nextMarkData); - /* mark cached function lookup data invalid; it will be set on first use */ + /* + * mark cached function lookup data invalid; it will be set on first + * use + */ scan->fn_getnext.fn_oid = InvalidOid; if (numberOfKeys > 0) diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c index 23356931198..e0672667c7f 100644 --- a/src/backend/access/index/indexam.c +++ b/src/backend/access/index/indexam.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.41 2000/03/14 23:52:01 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.42 2000/04/12 17:14:47 momjian Exp $ * * INTERFACE ROUTINES * index_open - open an index relation by relationId @@ -115,10 +115,10 @@ * index_open - open an index relation by relationId * * presently the relcache routines do all the work we need - * to open/close index relations. However, callers of index_open + * to open/close index relations. However, callers of index_open * expect it to succeed, so we need to check for a failure return. * - * Note: we acquire no lock on the index. An AccessShareLock is + * Note: we acquire no lock on the index. An AccessShareLock is * acquired by index_beginscan (and released by index_endscan). * ---------------- */ @@ -129,7 +129,7 @@ index_open(Oid relationId) r = RelationIdGetRelation(relationId); - if (! RelationIsValid(r)) + if (!RelationIsValid(r)) elog(ERROR, "Index %u does not exist", relationId); if (r->rd_rel->relkind != RELKIND_INDEX) @@ -151,7 +151,7 @@ index_openr(char *relationName) r = RelationNameGetRelation(relationName); - if (! RelationIsValid(r)) + if (!RelationIsValid(r)) elog(ERROR, "Index '%s' does not exist", relationName); if (r->rd_rel->relkind != RELKIND_INDEX) @@ -238,7 +238,7 @@ index_beginscan(Relation relation, * Acquire AccessShareLock for the duration of the scan * * Note: we could get an SI inval message here and consequently have - * to rebuild the relcache entry. The refcount increment above + * to rebuild the relcache entry. The refcount increment above * ensures that we will rebuild it and not just flush it... * ---------------- */ diff --git a/src/backend/access/index/istrat.c b/src/backend/access/index/istrat.c index fe956ead378..b0864e505fa 100644 --- a/src/backend/access/index/istrat.c +++ b/src/backend/access/index/istrat.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/index/Attic/istrat.c,v 1.41 2000/02/18 09:29:16 inoue Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/index/Attic/istrat.c,v 1.42 2000/04/12 17:14:47 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -477,7 +477,7 @@ OperatorRelationFillScanKeyEntry(Relation operatorRelation, { HeapTuple tuple; HeapScanDesc scan = NULL; - bool cachesearch = (!IsBootstrapProcessingMode()) && IsCacheInitialized(); + bool cachesearch = (!IsBootstrapProcessingMode()) && IsCacheInitialized(); if (cachesearch) { @@ -547,7 +547,7 @@ IndexSupportInitialize(IndexStrategy indexStrategy, AttrNumber attributeNumber; int attributeIndex; Oid operatorClassObjectId[INDEX_MAX_KEYS]; - bool cachesearch = (!IsBootstrapProcessingMode()) && IsCacheInitialized(); + bool cachesearch = (!IsBootstrapProcessingMode()) && IsCacheInitialized(); if (cachesearch) { @@ -674,7 +674,7 @@ IndexSupportInitialize(IndexStrategy indexStrategy, aform = (Form_pg_amop) GETSTRUCT(tuple); OperatorRelationFillScanKeyEntry(operatorRelation, aform->amopopr, - StrategyMapGetScanKeyEntry(map, aform->amopstrategy)); + StrategyMapGetScanKeyEntry(map, aform->amopstrategy)); } heap_endscan(scan); diff --git a/src/backend/access/nbtree/nbtcompare.c b/src/backend/access/nbtree/nbtcompare.c index f66b9a0e8e2..3e58c677a00 100644 --- a/src/backend/access/nbtree/nbtcompare.c +++ b/src/backend/access/nbtree/nbtcompare.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtcompare.c,v 1.33 2000/02/10 19:51:38 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtcompare.c,v 1.34 2000/04/12 17:14:49 momjian Exp $ * * NOTES * These functions are stored in pg_amproc. For each operator class @@ -35,12 +35,12 @@ btint2cmp(int16 a, int16 b) int32 btint4cmp(int32 a, int32 b) { - if (a > b) - return 1; - else if (a == b) - return 0; - else - return -1; + if (a > b) + return 1; + else if (a == b) + return 0; + else + return -1; } int32 diff --git a/src/backend/access/nbtree/nbtinsert.c b/src/backend/access/nbtree/nbtinsert.c index b891716a895..975b53d658a 100644 --- a/src/backend/access/nbtree/nbtinsert.c +++ b/src/backend/access/nbtree/nbtinsert.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.56 2000/03/17 02:36:03 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.57 2000/04/12 17:14:49 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -21,10 +21,10 @@ static InsertIndexResult _bt_insertonpg(Relation rel, Buffer buf, BTStack stack, int keysz, ScanKey scankey, BTItem btitem, BTItem afteritem); static Buffer _bt_split(Relation rel, Size keysz, ScanKey scankey, - Buffer buf, OffsetNumber firstright); + Buffer buf, OffsetNumber firstright); static OffsetNumber _bt_findsplitloc(Relation rel, Size keysz, ScanKey scankey, - Page page, OffsetNumber start, - OffsetNumber maxoff, Size llimit); + Page page, OffsetNumber start, + OffsetNumber maxoff, Size llimit); static void _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf); static OffsetNumber _bt_pgaddtup(Relation rel, Buffer buf, int keysz, ScanKey itup_scankey, Size itemsize, BTItem btitem, BTItem afteritem); static bool _bt_goesonpg(Relation rel, Buffer buf, Size keysz, ScanKey scankey, BTItem afteritem); @@ -267,21 +267,20 @@ _bt_insertonpg(Relation rel, itemsz = IndexTupleDSize(btitem->bti_itup) + (sizeof(BTItemData) - sizeof(IndexTupleData)); - itemsz = MAXALIGN(itemsz); /* be safe, PageAddItem will do - * this but we need to be - * consistent */ + itemsz = MAXALIGN(itemsz); /* be safe, PageAddItem will do this but + * we need to be consistent */ /* - * Check whether the item can fit on a btree page at all. - * (Eventually, we ought to try to apply TOAST methods if not.) - * We actually need to be able to fit three items on every page, - * so restrict any one item to 1/3 the per-page available space. - * Note that at this point, itemsz doesn't include the ItemId. + * Check whether the item can fit on a btree page at all. (Eventually, + * we ought to try to apply TOAST methods if not.) We actually need to + * be able to fit three items on every page, so restrict any one item + * to 1/3 the per-page available space. Note that at this point, + * itemsz doesn't include the ItemId. */ - if (itemsz > (PageGetPageSize(page)-sizeof(PageHeaderData)-MAXALIGN(sizeof(BTPageOpaqueData)))/3 - sizeof(ItemIdData)) + if (itemsz > (PageGetPageSize(page) - sizeof(PageHeaderData) - MAXALIGN(sizeof(BTPageOpaqueData))) / 3 - sizeof(ItemIdData)) elog(ERROR, "btree: index item size %u exceeds maximum %lu", itemsz, - (PageGetPageSize(page)-sizeof(PageHeaderData)-MAXALIGN(sizeof(BTPageOpaqueData)))/3 - sizeof(ItemIdData)); + (PageGetPageSize(page) - sizeof(PageHeaderData) - MAXALIGN(sizeof(BTPageOpaqueData))) /3 - sizeof(ItemIdData)); /* * If we have to insert item on the leftmost page which is the first @@ -415,8 +414,8 @@ _bt_insertonpg(Relation rel, bool is_root = lpageop->btpo_flags & BTP_ROOT; /* - * Instead of splitting leaf page in the chain of duplicates - * by new duplicate, insert it into some right page. + * Instead of splitting leaf page in the chain of duplicates by + * new duplicate, insert it into some right page. */ if ((lpageop->btpo_flags & BTP_CHAIN) && (lpageop->btpo_flags & BTP_LEAF) && keys_equal) @@ -424,8 +423,9 @@ _bt_insertonpg(Relation rel, rbuf = _bt_getbuf(rel, lpageop->btpo_next, BT_WRITE); rpage = BufferGetPage(rbuf); rpageop = (BTPageOpaque) PageGetSpecialPointer(rpage); - /* - * some checks + + /* + * some checks */ if (!P_RIGHTMOST(rpageop)) /* non-rightmost page */ { /* If we have the same hikey here then @@ -442,6 +442,7 @@ _bt_insertonpg(Relation rel, BTGreaterStrategyNumber)) elog(FATAL, "btree: hikey is out of order"); else if (rpageop->btpo_flags & BTP_CHAIN) + /* * If hikey > scankey then it's last page in chain and * BTP_CHAIN must be OFF @@ -450,9 +451,7 @@ _bt_insertonpg(Relation rel, } else /* rightmost page */ - { Assert(!(rpageop->btpo_flags & BTP_CHAIN)); - } _bt_relbuf(rel, buf, BT_WRITE); return (_bt_insertonpg(rel, rbuf, stack, keysz, scankey, btitem, afteritem)); @@ -708,7 +707,7 @@ l_spl: ; */ if (!parent_chained && MAXALIGN(IndexTupleDSize(lowLeftItem->bti_itup)) == - MAXALIGN(IndexTupleDSize(stack->bts_btitem->bti_itup))) + MAXALIGN(IndexTupleDSize(stack->bts_btitem->bti_itup))) { _bt_updateitem(rel, keysz, pbuf, stack->bts_btitem, lowLeftItem); diff --git a/src/backend/access/nbtree/nbtpage.c b/src/backend/access/nbtree/nbtpage.c index 60eaf3a9d23..1a623698f57 100644 --- a/src/backend/access/nbtree/nbtpage.c +++ b/src/backend/access/nbtree/nbtpage.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtpage.c,v 1.35 2000/01/26 05:55:58 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtpage.c,v 1.36 2000/04/12 17:14:49 momjian Exp $ * * NOTES * Postgres btree pages look like ordinary relation pages. The opaque @@ -257,7 +257,7 @@ _bt_getroot(Relation rel, int access) else { rootblkno = metad->btm_root; - _bt_relbuf(rel, metabuf, BT_READ); /* done with the meta page */ + _bt_relbuf(rel, metabuf, BT_READ); /* done with the meta page */ rootbuf = _bt_getbuf(rel, rootblkno, access); } diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c index da5dd70332e..72969d4d1b7 100644 --- a/src/backend/access/nbtree/nbtree.c +++ b/src/backend/access/nbtree/nbtree.c @@ -12,7 +12,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.53 2000/02/18 09:29:54 inoue Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.54 2000/04/12 17:14:49 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -77,7 +77,7 @@ btbuild(Relation heap, #endif Node *pred, *oldPred; - BTSpool *spool = NULL; + BTSpool *spool = NULL; bool isunique; bool usefast; @@ -185,7 +185,7 @@ btbuild(Relation heap, #ifndef OMIT_PARTIAL_INDEX /* SetSlotContents(slot, htup); */ slot->val = htup; - if (! ExecQual((List *) pred, econtext, false)) + if (!ExecQual((List *) pred, econtext, false)) continue; #endif /* OMIT_PARTIAL_INDEX */ } @@ -276,9 +276,9 @@ btbuild(Relation heap, } /* - * if we are doing bottom-up btree build, finish the build by - * (1) completing the sort of the spool file, (2) inserting the - * sorted tuples into btree pages and (3) building the upper levels. + * if we are doing bottom-up btree build, finish the build by (1) + * completing the sort of the spool file, (2) inserting the sorted + * tuples into btree pages and (3) building the upper levels. */ if (usefast) { @@ -298,26 +298,27 @@ btbuild(Relation heap, /* * Since we just counted the tuples in the heap, we update its stats * in pg_class to guarantee that the planner takes advantage of the - * index we just created. But, only update statistics during - * normal index definitions, not for indices on system catalogs - * created during bootstrap processing. We must close the relations - * before updating statistics to guarantee that the relcache entries - * are flushed when we increment the command counter in UpdateStats(). - * But we do not release any locks on the relations; those will be - * held until end of transaction. + * index we just created. But, only update statistics during normal + * index definitions, not for indices on system catalogs created + * during bootstrap processing. We must close the relations before + * updating statistics to guarantee that the relcache entries are + * flushed when we increment the command counter in UpdateStats(). But + * we do not release any locks on the relations; those will be held + * until end of transaction. */ if (IsNormalProcessingMode()) { - Oid hrelid = RelationGetRelid(heap); - Oid irelid = RelationGetRelid(index); + Oid hrelid = RelationGetRelid(heap); + Oid irelid = RelationGetRelid(index); bool inplace = IsReindexProcessing(); heap_close(heap, NoLock); index_close(index); + /* - UpdateStats(hrelid, nhtups, true); - UpdateStats(irelid, nitups, false); - */ + * UpdateStats(hrelid, nhtups, true); UpdateStats(irelid, nitups, + * false); + */ UpdateStats(hrelid, nhtups, inplace); UpdateStats(irelid, nitups, inplace); if (oldPred != NULL) @@ -623,7 +624,7 @@ _bt_restscan(IndexScanDesc scan) BTItem item; BlockNumber blkno; - LockBuffer(buf, BT_READ); /* lock buffer first! */ + LockBuffer(buf, BT_READ); /* lock buffer first! */ page = BufferGetPage(buf); maxoff = PageGetMaxOffsetNumber(page); opaque = (BTPageOpaque) PageGetSpecialPointer(page); diff --git a/src/backend/access/nbtree/nbtscan.c b/src/backend/access/nbtree/nbtscan.c index 95b1bf53ecb..37469365bcd 100644 --- a/src/backend/access/nbtree/nbtscan.c +++ b/src/backend/access/nbtree/nbtscan.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/nbtree/Attic/nbtscan.c,v 1.30 2000/01/26 05:55:58 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/nbtree/Attic/nbtscan.c,v 1.31 2000/04/12 17:14:49 momjian Exp $ * * * NOTES @@ -52,13 +52,16 @@ static void _bt_scandel(IndexScanDesc scan, BlockNumber blkno, OffsetNumber offn void AtEOXact_nbtree(void) { - /* Note: these actions should only be necessary during xact abort; - * but they can't hurt during a commit. + + /* + * Note: these actions should only be necessary during xact abort; but + * they can't hurt during a commit. */ - /* Reset the active-scans list to empty. - * We do not need to free the list elements, because they're all - * palloc()'d, so they'll go away at end of transaction anyway. + /* + * Reset the active-scans list to empty. We do not need to free the + * list elements, because they're all palloc()'d, so they'll go away + * at end of transaction anyway. */ BTScans = NULL; @@ -96,7 +99,7 @@ _bt_dropscan(IndexScanDesc scan) last = chk; if (chk == (BTScanList) NULL) - elog(ERROR, "btree scan list trashed; can't find 0x%p", (void*)scan); + elog(ERROR, "btree scan list trashed; can't find 0x%p", (void *) scan); if (last == (BTScanList) NULL) BTScans = chk->btsl_next; diff --git a/src/backend/access/nbtree/nbtsearch.c b/src/backend/access/nbtree/nbtsearch.c index f36da9743f8..cad117e5e61 100644 --- a/src/backend/access/nbtree/nbtsearch.c +++ b/src/backend/access/nbtree/nbtsearch.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.58 2000/03/17 02:36:04 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.59 2000/04/12 17:14:49 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -299,9 +299,7 @@ _bt_skeycmp(Relation rel, compare = -1; /* not-NULL key "<" NULL datum */ } else - { compare = (int32) FMGR_PTR2(&entry->sk_func, keyDatum, attrDatum); - } if (compare != 0) break; /* done when we find unequal attributes */ @@ -368,26 +366,26 @@ _bt_binsrch(Relation rel, /* * If there are no keys on the page, return the first available slot. - * Note this covers two cases: the page is really empty (no keys), - * or it contains only a high key. The latter case is possible after + * Note this covers two cases: the page is really empty (no keys), or + * it contains only a high key. The latter case is possible after * vacuuming. */ if (high < low) return low; /* - * Binary search to find the first key on the page >= scan key. - * Loop invariant: all slots before 'low' are < scan key, all slots - * at or after 'high' are >= scan key. Also, haveEq is true if the - * tuple at 'high' is == scan key. - * We can fall out when high == low. + * Binary search to find the first key on the page >= scan key. Loop + * invariant: all slots before 'low' are < scan key, all slots at or + * after 'high' are >= scan key. Also, haveEq is true if the tuple at + * 'high' is == scan key. We can fall out when high == low. */ high++; /* establish the loop invariant for high */ haveEq = false; while (high > low) { - OffsetNumber mid = low + ((high - low) / 2); + OffsetNumber mid = low + ((high - low) / 2); + /* We have low <= mid < high, so mid points at a real slot */ result = _bt_compare(rel, itupdesc, page, keysz, scankey, mid); @@ -403,7 +401,7 @@ _bt_binsrch(Relation rel, /*-------------------- * At this point we have high == low, but be careful: they could point - * past the last slot on the page. We also know that haveEq is true + * past the last slot on the page. We also know that haveEq is true * if and only if there is an equal key (in which case high&low point * at the first equal key). * @@ -443,18 +441,20 @@ _bt_binsrch(Relation rel, if (haveEq) { + /* * There is an equal key. We return either the first equal key * (which we just found), or the last lesser key. * - * We need not check srchtype != BT_DESCENT here, since if that - * is true then natts == keysz by assumption. + * We need not check srchtype != BT_DESCENT here, since if that is + * true then natts == keysz by assumption. */ if (natts == keysz) return low; /* return first equal key */ } else { + /* * There is no equal key. We return either the first greater key * (which we just found), or the last lesser key. @@ -524,6 +524,7 @@ _bt_compare(Relation rel, && P_LEFTMOST(opaque) && offnum == P_HIKEY) { + /* * we just have to believe that this will only be called with * offnum == P_HIKEY when P_HIKEY is the OffsetNumber of the first @@ -702,11 +703,12 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) bool strategyCheck; ScanKey scankeys = 0; - int keysCount = 0; - int *nKeyIs = 0; - int i, j; - StrategyNumber strat_total; - + int keysCount = 0; + int *nKeyIs = 0; + int i, + j; + StrategyNumber strat_total; + rel = scan->relation; so = (BTScanOpaque) scan->opaque; @@ -723,15 +725,15 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) _bt_orderkeys(rel, so); if (so->qual_ok) - strategyCheck = true; - } + strategyCheck = true; + } strat_total = BTEqualStrategyNumber; if (strategyCheck) { AttrNumber attno; - nKeyIs = (int *)palloc(so->numberOfKeys*sizeof(int)); - for (i=0; i < so->numberOfKeys; i++) + nKeyIs = (int *) palloc(so->numberOfKeys * sizeof(int)); + for (i = 0; i < so->numberOfKeys; i++) { attno = so->keyData[i].sk_attno; if (attno == keysCount) @@ -739,16 +741,16 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) if (attno > keysCount + 1) break; strat = _bt_getstrat(rel, attno, - so->keyData[i].sk_procedure); + so->keyData[i].sk_procedure); if (strat == strat_total || - strat == BTEqualStrategyNumber) + strat == BTEqualStrategyNumber) { nKeyIs[keysCount++] = i; continue; } if (ScanDirectionIsBackward(dir) && - (strat == BTLessStrategyNumber || - strat == BTLessEqualStrategyNumber) ) + (strat == BTLessStrategyNumber || + strat == BTLessEqualStrategyNumber)) { nKeyIs[keysCount++] = i; strat_total = strat; @@ -757,8 +759,8 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) continue; } if (ScanDirectionIsForward(dir) && - (strat == BTGreaterStrategyNumber || - strat == BTGreaterEqualStrategyNumber) ) + (strat == BTGreaterStrategyNumber || + strat == BTGreaterEqualStrategyNumber)) { nKeyIs[keysCount++] = i; strat_total = strat; @@ -794,8 +796,8 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) * at the right place in the scan. */ /* _bt_orderkeys disallows it, but it's place to add some code latter */ - scankeys = (ScanKey)palloc(keysCount*sizeof(ScanKeyData)); - for (i=0; i < keysCount; i++) + scankeys = (ScanKey) palloc(keysCount * sizeof(ScanKeyData)); + for (i = 0; i < keysCount; i++) { j = nKeyIs[i]; if (so->keyData[j].sk_flags & SK_ISNULL) @@ -804,12 +806,13 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) pfree(scankeys); elog(ERROR, "_bt_first: btree doesn't support is(not)null, yet"); return ((RetrieveIndexResult) NULL); - } - proc = index_getprocid(rel, i+1, BTORDER_PROC); - ScanKeyEntryInitialize(scankeys+i, so->keyData[j].sk_flags, - i+1, proc, so->keyData[j].sk_argument); + } + proc = index_getprocid(rel, i + 1, BTORDER_PROC); + ScanKeyEntryInitialize(scankeys + i, so->keyData[j].sk_flags, + i + 1, proc, so->keyData[j].sk_argument); } - if (nKeyIs) pfree(nKeyIs); + if (nKeyIs) + pfree(nKeyIs); stack = _bt_search(rel, keysCount, scankeys, &buf); _bt_freestack(stack); diff --git a/src/backend/access/nbtree/nbtsort.c b/src/backend/access/nbtree/nbtsort.c index f9cbf7121ff..65e757e42b3 100644 --- a/src/backend/access/nbtree/nbtsort.c +++ b/src/backend/access/nbtree/nbtsort.c @@ -6,7 +6,7 @@ * * We use tuplesort.c to sort the given index tuples into order. * Then we scan the index tuples in order and build the btree pages - * for each level. When we have only one page on a level, it must be the + * for each level. When we have only one page on a level, it must be the * root -- it can be attached to the btree metapage and we are done. * * this code is moderately slow (~10% slower) compared to the regular @@ -28,7 +28,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsort.c,v 1.51 2000/02/18 06:32:39 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsort.c,v 1.52 2000/04/12 17:14:49 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -70,12 +70,12 @@ struct BTSpool static void _bt_load(Relation index, BTSpool *btspool); static BTItem _bt_buildadd(Relation index, Size keysz, ScanKey scankey, - BTPageState *state, BTItem bti, int flags); + BTPageState *state, BTItem bti, int flags); static BTItem _bt_minitem(Page opage, BlockNumber oblkno, int atend); static BTPageState *_bt_pagestate(Relation index, int flags, - int level, bool doupper); + int level, bool doupper); static void _bt_uppershutdown(Relation index, Size keysz, ScanKey scankey, - BTPageState *state); + BTPageState *state); /* @@ -86,7 +86,7 @@ static void _bt_uppershutdown(Relation index, Size keysz, ScanKey scankey, /* * create and initialize a spool structure */ -BTSpool * +BTSpool * _bt_spoolinit(Relation index, bool isunique) { BTSpool *btspool = (BTSpool *) palloc(sizeof(BTSpool)); @@ -99,9 +99,9 @@ _bt_spoolinit(Relation index, bool isunique) btspool->sortstate = tuplesort_begin_index(index, isunique, false); /* - * Currently, tuplesort provides sort functions on IndexTuples. - * If we kept anything in a BTItem other than a regular IndexTuple, - * we'd need to modify tuplesort to understand BTItems as such. + * Currently, tuplesort provides sort functions on IndexTuples. If we + * kept anything in a BTItem other than a regular IndexTuple, we'd + * need to modify tuplesort to understand BTItems as such. */ Assert(sizeof(BTItemData) == sizeof(IndexTupleData)); @@ -306,20 +306,20 @@ _bt_buildadd(Relation index, Size keysz, ScanKey scankey, btisz = MAXALIGN(btisz); /* - * Check whether the item can fit on a btree page at all. - * (Eventually, we ought to try to apply TOAST methods if not.) - * We actually need to be able to fit three items on every page, - * so restrict any one item to 1/3 the per-page available space. - * Note that at this point, btisz doesn't include the ItemId. + * Check whether the item can fit on a btree page at all. (Eventually, + * we ought to try to apply TOAST methods if not.) We actually need to + * be able to fit three items on every page, so restrict any one item + * to 1/3 the per-page available space. Note that at this point, btisz + * doesn't include the ItemId. * * NOTE: similar code appears in _bt_insertonpg() to defend against - * oversize items being inserted into an already-existing index. - * But during creation of an index, we don't go through there. + * oversize items being inserted into an already-existing index. But + * during creation of an index, we don't go through there. */ - if (btisz > (PageGetPageSize(npage)-sizeof(PageHeaderData)-MAXALIGN(sizeof(BTPageOpaqueData)))/3 - sizeof(ItemIdData)) + if (btisz > (PageGetPageSize(npage) - sizeof(PageHeaderData) - MAXALIGN(sizeof(BTPageOpaqueData))) / 3 - sizeof(ItemIdData)) elog(ERROR, "btree: index item size %d exceeds maximum %ld", btisz, - (PageGetPageSize(npage)-sizeof(PageHeaderData)-MAXALIGN(sizeof(BTPageOpaqueData)))/3 - sizeof(ItemIdData)); + (PageGetPageSize(npage) - sizeof(PageHeaderData) - MAXALIGN(sizeof(BTPageOpaqueData))) /3 - sizeof(ItemIdData)); if (pgspc < btisz) { diff --git a/src/backend/access/nbtree/nbtutils.c b/src/backend/access/nbtree/nbtutils.c index 9d1cc7b10d0..38b152e61b2 100644 --- a/src/backend/access/nbtree/nbtutils.c +++ b/src/backend/access/nbtree/nbtutils.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtutils.c,v 1.35 2000/02/18 06:32:39 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtutils.c,v 1.36 2000/04/12 17:14:50 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -141,7 +141,8 @@ _bt_orderkeys(Relation relation, BTScanOpaque so) uint16 numberOfKeys = so->numberOfKeys; uint16 new_numberOfKeys = 0; AttrNumber attno = 1; - bool equalStrategyEnd, underEqualStrategy; + bool equalStrategyEnd, + underEqualStrategy; if (numberOfKeys < 1) return; @@ -194,6 +195,7 @@ _bt_orderkeys(Relation relation, BTScanOpaque so) elog(ERROR, "_bt_orderkeys: key(s) for attribute %d missed", attno + 1); underEqualStrategy = (!equalStrategyEnd); + /* * If = has been specified, no other key will be used. In case * of key < 2 && key == 1 and so on we have to set qual_ok to diff --git a/src/backend/access/rtree/rtree.c b/src/backend/access/rtree/rtree.c index 34cf0b6c937..53e5345a55d 100644 --- a/src/backend/access/rtree/rtree.c +++ b/src/backend/access/rtree/rtree.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtree.c,v 1.44 2000/03/01 05:39:23 inoue Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtree.c,v 1.45 2000/04/12 17:14:51 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -181,7 +181,7 @@ rtbuild(Relation heap, #ifndef OMIT_PARTIAL_INDEX /* SetSlotContents(slot, htup); */ slot->val = htup; - if (! ExecQual((List *) pred, econtext, false)) + if (!ExecQual((List *) pred, econtext, false)) continue; #endif /* OMIT_PARTIAL_INDEX */ } @@ -249,18 +249,18 @@ rtbuild(Relation heap, /* * Since we just counted the tuples in the heap, we update its stats * in pg_class to guarantee that the planner takes advantage of the - * index we just created. But, only update statistics during - * normal index definitions, not for indices on system catalogs - * created during bootstrap processing. We must close the relations - * before updating statistics to guarantee that the relcache entries - * are flushed when we increment the command counter in UpdateStats(). - * But we do not release any locks on the relations; those will be - * held until end of transaction. + * index we just created. But, only update statistics during normal + * index definitions, not for indices on system catalogs created + * during bootstrap processing. We must close the relations before + * updating statistics to guarantee that the relcache entries are + * flushed when we increment the command counter in UpdateStats(). But + * we do not release any locks on the relations; those will be held + * until end of transaction. */ if (IsNormalProcessingMode()) { - Oid hrelid = RelationGetRelid(heap); - Oid irelid = RelationGetRelid(index); + Oid hrelid = RelationGetRelid(heap); + Oid irelid = RelationGetRelid(index); bool inplace = IsReindexProcessing(); heap_close(heap, NoLock); diff --git a/src/backend/access/rtree/rtscan.c b/src/backend/access/rtree/rtscan.c index ada38612778..71e2acf5f88 100644 --- a/src/backend/access/rtree/rtscan.c +++ b/src/backend/access/rtree/rtscan.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtscan.c,v 1.31 2000/01/26 05:56:00 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtscan.c,v 1.32 2000/04/12 17:14:51 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -268,7 +268,7 @@ rtdropscan(IndexScanDesc s) prev = l; if (l == (RTScanList) NULL) - elog(ERROR, "rtree scan list corrupted -- cannot find 0x%p", (void*)s); + elog(ERROR, "rtree scan list corrupted -- cannot find 0x%p", (void *) s); if (prev == (RTScanList) NULL) RTScans = l->rtsl_next; diff --git a/src/backend/access/transam/rmgr.c b/src/backend/access/transam/rmgr.c index 36d50f08c0c..4efb53ea08c 100644 --- a/src/backend/access/transam/rmgr.c +++ b/src/backend/access/transam/rmgr.c @@ -1,4 +1,4 @@ #include "postgres.h" #include "access/rmgr.h" -RmgrData *RmgrTable = NULL; +RmgrData *RmgrTable = NULL; diff --git a/src/backend/access/transam/transam.c b/src/backend/access/transam/transam.c index a5af2bdc533..acca4a901a2 100644 --- a/src/backend/access/transam/transam.c +++ b/src/backend/access/transam/transam.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/transam/transam.c,v 1.33 2000/01/26 05:56:03 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/transam/transam.c,v 1.34 2000/04/12 17:14:52 momjian Exp $ * * NOTES * This file contains the high level access-method interface to the @@ -162,6 +162,7 @@ TransactionLogTest(TransactionId transactionId, /* transaction id to test */ if (!fail) { + /* * DO NOT cache status for transactions in unknown state !!! */ diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 6a31bfe429e..5ce334aa299 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/transam/varsup.c,v 1.27 2000/03/31 02:43:31 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/transam/varsup.c,v 1.28 2000/04/12 17:14:53 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -331,8 +331,8 @@ ReadNewTransactionId(TransactionId *xid) SpinAcquire(OidGenLockId); /* not good for concurrency... */ /* - * Note that we don't check is ShmemVariableCache->xid_count equal - * to 0 or not. This will work as long as we don't call + * Note that we don't check is ShmemVariableCache->xid_count equal to + * 0 or not. This will work as long as we don't call * ReadNewTransactionId() before GetNewTransactionId(). */ if (ShmemVariableCache->nextXid == 0) diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c index 2522cca46c1..688741511fb 100644 --- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.63 2000/04/09 04:43:16 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.64 2000/04/12 17:14:53 momjian Exp $ * * NOTES * Transaction aborts can now occur two ways: @@ -160,7 +160,7 @@ #include "utils/portal.h" #include "utils/relcache.h" -extern bool SharedBufferChanged; +extern bool SharedBufferChanged; static void AbortTransaction(void); static void AtAbort_Cache(void); @@ -517,8 +517,8 @@ CommandCounterIncrement() CurrentTransactionStateData.scanCommandId = CurrentTransactionStateData.commandId; /* - * make cache changes visible to me. AtCommit_LocalCache() - * instead of AtCommit_Cache() is called here. + * make cache changes visible to me. AtCommit_LocalCache() instead of + * AtCommit_Cache() is called here. */ AtCommit_LocalCache(); AtStart_Cache(); @@ -627,16 +627,15 @@ RecordTransactionCommit() */ xid = GetCurrentTransactionId(); - /* - * flush the buffer manager pages. Note: if we have stable - * main memory, dirty shared buffers are not flushed - * plai 8/7/90 + /* + * flush the buffer manager pages. Note: if we have stable main + * memory, dirty shared buffers are not flushed plai 8/7/90 */ leak = BufferPoolCheckLeak(); /* - * If no one shared buffer was changed by this transaction then - * we don't flush shared buffers and don't record commit status. + * If no one shared buffer was changed by this transaction then we + * don't flush shared buffers and don't record commit status. */ if (SharedBufferChanged) { @@ -645,13 +644,13 @@ RecordTransactionCommit() ResetBufferPool(true); /* - * have the transaction access methods record the status - * of this transaction id in the pg_log relation. + * have the transaction access methods record the status of this + * transaction id in the pg_log relation. */ TransactionIdCommit(xid); /* - * Now write the log info to the disk too. + * Now write the log info to the disk too. */ leak = BufferPoolCheckLeak(); FlushBufferPool(); @@ -751,10 +750,10 @@ RecordTransactionAbort() */ xid = GetCurrentTransactionId(); - /* - * Have the transaction access methods record the status of - * this transaction id in the pg_log relation. We skip it - * if no one shared buffer was changed by this transaction. + /* + * Have the transaction access methods record the status of this + * transaction id in the pg_log relation. We skip it if no one shared + * buffer was changed by this transaction. */ if (SharedBufferChanged && !TransactionIdDidCommit(xid)) TransactionIdAbort(xid); @@ -936,7 +935,7 @@ CommitTransaction() /* ---------------- * Tell the trigger manager that this transaction is about to be * committed. He'll invoke all trigger deferred until XACT before - * we really start on committing the transaction. + * we really start on committing the transaction. * ---------------- */ DeferredTriggerEndXact(); @@ -965,13 +964,13 @@ CommitTransaction() RecordTransactionCommit(); /* - * Let others know about no transaction in progress by me. - * Note that this must be done _before_ releasing locks we hold - * and SpinAcquire(SInvalLock) is required: UPDATE with xid 0 is - * blocked by xid 1' UPDATE, xid 1 is doing commit while xid 2 - * gets snapshot - if xid 2' GetSnapshotData sees xid 1 as running - * then it must see xid 0 as running as well or it will see two - * tuple versions - one deleted by xid 1 and one inserted by xid 0. + * Let others know about no transaction in progress by me. Note that + * this must be done _before_ releasing locks we hold and + * SpinAcquire(SInvalLock) is required: UPDATE with xid 0 is blocked + * by xid 1' UPDATE, xid 1 is doing commit while xid 2 gets snapshot - + * if xid 2' GetSnapshotData sees xid 1 as running then it must see + * xid 0 as running as well or it will see two tuple versions - one + * deleted by xid 1 and one inserted by xid 0. */ if (MyProc != (PROC *) NULL) { @@ -995,7 +994,7 @@ CommitTransaction() * ---------------- */ s->state = TRANS_DEFAULT; - SharedBufferChanged = false; /* safest place to do it */ + SharedBufferChanged = false;/* safest place to do it */ } @@ -1031,7 +1030,7 @@ AbortTransaction() /* ---------------- * Tell the trigger manager that this transaction is about to be - * aborted. + * aborted. * ---------------- */ DeferredTriggerAbortXact(); @@ -1070,7 +1069,7 @@ AbortTransaction() * ---------------- */ s->state = TRANS_DEFAULT; - SharedBufferChanged = false; /* safest place to do it */ + SharedBufferChanged = false;/* safest place to do it */ } /* -------------------------------- diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 7d197cb5a3a..b672cf2c7a9 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -1,4 +1,4 @@ -/*------------------------------------------------------------------------- +/*------------------------------------------------------------------------- * * xlog.c * @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * - * $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.12 2000/03/20 07:25:39 vadim Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.13 2000/04/12 17:14:53 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -44,64 +44,64 @@ bool StopIfError = false; SPINLOCK ControlFileLockId; SPINLOCK XidGenLockId; -extern bool ReleaseDataFile(void); +extern bool ReleaseDataFile(void); -extern VariableCache ShmemVariableCache; +extern VariableCache ShmemVariableCache; -#define MinXLOGbuffers 4 +#define MinXLOGbuffers 4 typedef struct XLgwrRqst { - XLogRecPtr Write; /* byte (1-based) to write out */ - XLogRecPtr Flush; /* byte (1-based) to flush */ + XLogRecPtr Write; /* byte (1-based) to write out */ + XLogRecPtr Flush; /* byte (1-based) to flush */ } XLgwrRqst; typedef struct XLgwrResult { - XLogRecPtr Write; /* bytes written out */ - XLogRecPtr Flush; /* bytes flushed */ + XLogRecPtr Write; /* bytes written out */ + XLogRecPtr Flush; /* bytes flushed */ } XLgwrResult; typedef struct XLogCtlInsert { - XLgwrResult LgwrResult; - XLogRecPtr PrevRecord; - uint16 curridx; /* current block index in cache */ - XLogPageHeader currpage; - char *currpos; + XLgwrResult LgwrResult; + XLogRecPtr PrevRecord; + uint16 curridx; /* current block index in cache */ + XLogPageHeader currpage; + char *currpos; } XLogCtlInsert; typedef struct XLogCtlWrite { - XLgwrResult LgwrResult; - uint16 curridx; /* index of next block to write */ + XLgwrResult LgwrResult; + uint16 curridx; /* index of next block to write */ } XLogCtlWrite; #ifndef HAS_TEST_AND_SET -#define TAS(lck) 0 -#define S_UNLOCK(lck) -#define S_INIT_LOCK(lck) +#define TAS(lck) 0 +#define S_UNLOCK(lck) +#define S_INIT_LOCK(lck) #endif typedef struct XLogCtlData { - XLogCtlInsert Insert; - XLgwrRqst LgwrRqst; - XLgwrResult LgwrResult; - XLogCtlWrite Write; - char *pages; - XLogRecPtr *xlblocks; /* 1st byte ptr-s + BLCKSZ */ - uint32 XLogCacheByte; - uint32 XLogCacheBlck; + XLogCtlInsert Insert; + XLgwrRqst LgwrRqst; + XLgwrResult LgwrResult; + XLogCtlWrite Write; + char *pages; + XLogRecPtr *xlblocks; /* 1st byte ptr-s + BLCKSZ */ + uint32 XLogCacheByte; + uint32 XLogCacheBlck; #ifdef HAS_TEST_AND_SET - slock_t insert_lck; - slock_t info_lck; - slock_t lgwr_lck; + slock_t insert_lck; + slock_t info_lck; + slock_t lgwr_lck; #endif } XLogCtlData; -static XLogCtlData *XLogCtl = NULL; +static XLogCtlData *XLogCtl = NULL; typedef enum DBState { @@ -114,69 +114,69 @@ typedef enum DBState typedef struct ControlFileData { - uint32 logId; /* current log file id */ - uint32 logSeg; /* current log file segment (1-based) */ - XLogRecPtr checkPoint; /* last check point record ptr */ - time_t time; /* time stamp of last modification */ - DBState state; /* */ + uint32 logId; /* current log file id */ + uint32 logSeg; /* current log file segment (1-based) */ + XLogRecPtr checkPoint; /* last check point record ptr */ + time_t time; /* time stamp of last modification */ + DBState state; /* */ /* - * this data is used to make sure that configuration of this DB - * is compatible with the current backend + * this data is used to make sure that configuration of this DB is + * compatible with the current backend */ - uint32 blcksz; /* block size for this DB */ - uint32 relseg_size; /* blocks per segment of large relation */ - uint32 catalog_version_no; /* internal version number */ + uint32 blcksz; /* block size for this DB */ + uint32 relseg_size; /* blocks per segment of large relation */ + uint32 catalog_version_no; /* internal version number */ /* - * MORE DATA FOLLOWS AT THE END OF THIS STRUCTURE - * - locations of data dirs + * MORE DATA FOLLOWS AT THE END OF THIS STRUCTURE - locations of data + * dirs */ } ControlFileData; -static ControlFileData *ControlFile = NULL; +static ControlFileData *ControlFile = NULL; typedef struct CheckPoint { - XLogRecPtr redo; /* next RecPtr available when we */ - /* began to create CheckPoint */ - /* (i.e. REDO start point) */ - XLogRecPtr undo; /* first record of oldest in-progress */ - /* transaction when we started */ - /* (i.e. UNDO end point) */ - TransactionId nextXid; - Oid nextOid; + XLogRecPtr redo; /* next RecPtr available when we */ + /* began to create CheckPoint */ + /* (i.e. REDO start point) */ + XLogRecPtr undo; /* first record of oldest in-progress */ + /* transaction when we started */ + /* (i.e. UNDO end point) */ + TransactionId nextXid; + Oid nextOid; } CheckPoint; -/* - * We break each log file in 16Mb segments +/* + * We break each log file in 16Mb segments */ #define XLogSegSize (16*1024*1024) -#define XLogLastSeg (0xffffffff / XLogSegSize) -#define XLogFileSize (XLogLastSeg * XLogSegSize) +#define XLogLastSeg (0xffffffff / XLogSegSize) +#define XLogFileSize (XLogLastSeg * XLogSegSize) -#define XLogFileName(path, log, seg) \ +#define XLogFileName(path, log, seg) \ snprintf(path, MAXPGPATH, "%s%c%08X%08X", \ XLogDir, SEP_CHAR, log, seg) -#define PrevBufIdx(curridx) \ +#define PrevBufIdx(curridx) \ ((curridx == 0) ? XLogCtl->XLogCacheBlck : (curridx - 1)) -#define NextBufIdx(curridx) \ +#define NextBufIdx(curridx) \ ((curridx == XLogCtl->XLogCacheBlck) ? 0 : (curridx + 1)) -#define XLByteLT(left, right) \ +#define XLByteLT(left, right) \ (right.xlogid > left.xlogid || \ (right.xlogid == left.xlogid && right.xrecoff > left.xrecoff)) -#define XLByteLE(left, right) \ +#define XLByteLE(left, right) \ (right.xlogid > left.xlogid || \ (right.xlogid == left.xlogid && right.xrecoff >= left.xrecoff)) -#define XLByteEQ(left, right) \ +#define XLByteEQ(left, right) \ (right.xlogid == left.xlogid && right.xrecoff == left.xrecoff) -#define InitXLBuffer(curridx) (\ +#define InitXLBuffer(curridx) (\ XLogCtl->xlblocks[curridx].xrecoff = \ (XLogCtl->xlblocks[Insert->curridx].xrecoff == XLogFileSize) ? \ BLCKSZ : (XLogCtl->xlblocks[Insert->curridx].xrecoff + BLCKSZ), \ @@ -192,46 +192,46 @@ typedef struct CheckPoint Insert->currpage->xlp_info = 0 \ ) -#define XRecOffIsValid(xrecoff) \ +#define XRecOffIsValid(xrecoff) \ (xrecoff % BLCKSZ >= SizeOfXLogPHD && \ (BLCKSZ - xrecoff % BLCKSZ) >= SizeOfXLogRecord) -static void GetFreeXLBuffer(void); -static void XLogWrite(char *buffer); -static int XLogFileInit(uint32 log, uint32 seg); -static int XLogFileOpen(uint32 log, uint32 seg, bool econt); -static XLogRecord *ReadRecord(XLogRecPtr *RecPtr, char *buffer); -static char *str_time(time_t tnow); - -static XLgwrResult LgwrResult = {{0, 0}, {0, 0}}; -static XLgwrRqst LgwrRqst = {{0, 0}, {0, 0}}; - -static int logFile = -1; -static uint32 logId = 0; -static uint32 logSeg = 0; -static uint32 logOff = 0; - -static XLogRecPtr ReadRecPtr; -static XLogRecPtr EndRecPtr; -static int readFile = -1; -static uint32 readId = 0; -static uint32 readSeg = 0; -static uint32 readOff = 0; -static char readBuf[BLCKSZ]; -static XLogRecord *nextRecord = NULL; +static void GetFreeXLBuffer(void); +static void XLogWrite(char *buffer); +static int XLogFileInit(uint32 log, uint32 seg); +static int XLogFileOpen(uint32 log, uint32 seg, bool econt); +static XLogRecord *ReadRecord(XLogRecPtr *RecPtr, char *buffer); +static char *str_time(time_t tnow); + +static XLgwrResult LgwrResult = {{0, 0}, {0, 0}}; +static XLgwrRqst LgwrRqst = {{0, 0}, {0, 0}}; + +static int logFile = -1; +static uint32 logId = 0; +static uint32 logSeg = 0; +static uint32 logOff = 0; + +static XLogRecPtr ReadRecPtr; +static XLogRecPtr EndRecPtr; +static int readFile = -1; +static uint32 readId = 0; +static uint32 readSeg = 0; +static uint32 readOff = 0; +static char readBuf[BLCKSZ]; +static XLogRecord *nextRecord = NULL; XLogRecPtr XLogInsert(RmgrId rmid, char *hdr, uint32 hdrlen, char *buf, uint32 buflen) { - XLogCtlInsert *Insert = &XLogCtl->Insert; - XLogRecord *record; - XLogSubRecord *subrecord; - XLogRecPtr RecPtr; - uint32 len = hdrlen + buflen, - freespace, - wlen; - uint16 curridx; - bool updrqst = false; + XLogCtlInsert *Insert = &XLogCtl->Insert; + XLogRecord *record; + XLogSubRecord *subrecord; + XLogRecPtr RecPtr; + uint32 len = hdrlen + buflen, + freespace, + wlen; + uint16 curridx; + bool updrqst = false; if (len == 0 || len > MAXLOGRECSZ) elog(STOP, "XLogInsert: invalid record len %u", len); @@ -242,7 +242,7 @@ XLogInsert(RmgrId rmid, char *hdr, uint32 hdrlen, char *buf, uint32 buflen) bool do_lgwr = true; unsigned i = 0; - for ( ; ; ) + for (;;) { /* try to read LgwrResult while waiting for insert lock */ if (!TAS(&(XLogCtl->info_lck))) @@ -250,14 +250,15 @@ XLogInsert(RmgrId rmid, char *hdr, uint32 hdrlen, char *buf, uint32 buflen) LgwrRqst = XLogCtl->LgwrRqst; LgwrResult = XLogCtl->LgwrResult; S_UNLOCK(&(XLogCtl->info_lck)); + /* * If cache is half filled then try to acquire lgwr lock * and do LGWR work, but only once. */ - if (do_lgwr && - (LgwrRqst.Write.xlogid != LgwrResult.Write.xlogid || - (LgwrRqst.Write.xrecoff - LgwrResult.Write.xrecoff >= - XLogCtl->XLogCacheByte / 2))) + if (do_lgwr && + (LgwrRqst.Write.xlogid != LgwrResult.Write.xlogid || + (LgwrRqst.Write.xrecoff - LgwrResult.Write.xrecoff >= + XLogCtl->XLogCacheByte / 2))) { if (!TAS(&(XLogCtl->lgwr_lck))) { @@ -282,13 +283,13 @@ XLogInsert(RmgrId rmid, char *hdr, uint32 hdrlen, char *buf, uint32 buflen) } } - freespace = ((char*) Insert->currpage) + BLCKSZ - Insert->currpos; + freespace = ((char *) Insert->currpage) + BLCKSZ - Insert->currpos; if (freespace < SizeOfXLogRecord) { curridx = NextBufIdx(Insert->curridx); if (XLByteLE(XLogCtl->xlblocks[curridx], LgwrResult.Write)) InitXLBuffer(curridx); - else + else GetFreeXLBuffer(); freespace = BLCKSZ - SizeOfXLogPHD; } @@ -296,7 +297,7 @@ XLogInsert(RmgrId rmid, char *hdr, uint32 hdrlen, char *buf, uint32 buflen) curridx = Insert->curridx; freespace -= SizeOfXLogRecord; - record = (XLogRecord*) Insert->currpos; + record = (XLogRecord *) Insert->currpos; record->xl_prev = Insert->PrevRecord; if (rmid != RM_XLOG_ID) record->xl_xact_prev = MyLastRecPtr; @@ -310,9 +311,9 @@ XLogInsert(RmgrId rmid, char *hdr, uint32 hdrlen, char *buf, uint32 buflen) record->xl_info = (len > freespace) ? XLR_TO_BE_CONTINUED : 0; record->xl_rmid = rmid; RecPtr.xlogid = XLogCtl->xlblocks[curridx].xlogid; - RecPtr.xrecoff = - XLogCtl->xlblocks[curridx].xrecoff - BLCKSZ + - Insert->currpos - ((char*) Insert->currpage); + RecPtr.xrecoff = + XLogCtl->xlblocks[curridx].xrecoff - BLCKSZ + + Insert->currpos - ((char *) Insert->currpage); if (MyLastRecPtr.xrecoff == 0 && rmid != RM_XLOG_ID) { SpinAcquire(SInvalLock); @@ -339,8 +340,8 @@ XLogInsert(RmgrId rmid, char *hdr, uint32 hdrlen, char *buf, uint32 buflen) buf += wlen; Insert->currpos += wlen; } - Insert->currpos = ((char*)Insert->currpage) + - DOUBLEALIGN(Insert->currpos - ((char*)Insert->currpage)); + Insert->currpos = ((char *) Insert->currpage) + + DOUBLEALIGN(Insert->currpos - ((char *) Insert->currpage)); len = hdrlen + buflen; } @@ -360,7 +361,7 @@ nbuf: } freespace = BLCKSZ - SizeOfXLogPHD - SizeOfXLogSubRecord; Insert->currpage->xlp_info |= XLP_FIRST_IS_SUBRECORD; - subrecord = (XLogSubRecord*) Insert->currpos; + subrecord = (XLogSubRecord *) Insert->currpos; Insert->currpos += SizeOfXLogSubRecord; if (hdrlen > freespace) { @@ -398,17 +399,19 @@ nbuf: } subrecord->xl_info = 0; RecPtr.xlogid = XLogCtl->xlblocks[curridx].xlogid; - RecPtr.xrecoff = XLogCtl->xlblocks[curridx].xrecoff - - BLCKSZ + SizeOfXLogPHD + subrecord->xl_len; - Insert->currpos = ((char*)Insert->currpage) + - DOUBLEALIGN(Insert->currpos - ((char*)Insert->currpage)); + RecPtr.xrecoff = XLogCtl->xlblocks[curridx].xrecoff - + BLCKSZ + SizeOfXLogPHD + subrecord->xl_len; + Insert->currpos = ((char *) Insert->currpage) + + DOUBLEALIGN(Insert->currpos - ((char *) Insert->currpage)); } - freespace = ((char*) Insert->currpage) + BLCKSZ - Insert->currpos; + freespace = ((char *) Insert->currpage) + BLCKSZ - Insert->currpos; + /* * All done! Update global LgwrRqst if some block was filled up. */ if (freespace < SizeOfXLogRecord) - updrqst = true; /* curridx is filled and available for writing out */ + updrqst = true; /* curridx is filled and available for + * writing out */ else curridx = PrevBufIdx(curridx); LgwrRqst.Write = XLogCtl->xlblocks[curridx]; @@ -419,7 +422,7 @@ nbuf: { unsigned i = 0; - for ( ; ; ) + for (;;) { if (!TAS(&(XLogCtl->info_lck))) { @@ -433,21 +436,21 @@ nbuf: } return (RecPtr); -} +} void XLogFlush(XLogRecPtr record) { - XLogRecPtr WriteRqst; - char buffer[BLCKSZ]; - char *usebuf = NULL; - unsigned i = 0; - bool force_lgwr = false; + XLogRecPtr WriteRqst; + char buffer[BLCKSZ]; + char *usebuf = NULL; + unsigned i = 0; + bool force_lgwr = false; if (XLByteLE(record, LgwrResult.Flush)) return; WriteRqst = LgwrRqst.Write; - for ( ; ; ) + for (;;) { /* try to read LgwrResult */ if (!TAS(&(XLogCtl->info_lck))) @@ -470,9 +473,9 @@ XLogFlush(XLogRecPtr record) /* if something was added to log cache then try to flush this too */ if (!TAS(&(XLogCtl->insert_lck))) { - XLogCtlInsert *Insert = &XLogCtl->Insert; - uint32 freespace = - ((char*) Insert->currpage) + BLCKSZ - Insert->currpos; + XLogCtlInsert *Insert = &XLogCtl->Insert; + uint32 freespace = + ((char *) Insert->currpage) + BLCKSZ - Insert->currpos; if (freespace < SizeOfXLogRecord) /* buffer is full */ { @@ -485,14 +488,14 @@ XLogFlush(XLogRecPtr record) memcpy(usebuf, Insert->currpage, BLCKSZ - freespace); memset(usebuf + BLCKSZ - freespace, 0, freespace); WriteRqst = XLogCtl->xlblocks[Insert->curridx]; - WriteRqst.xrecoff = WriteRqst.xrecoff - BLCKSZ + - Insert->currpos - ((char*) Insert->currpage); + WriteRqst.xrecoff = WriteRqst.xrecoff - BLCKSZ + + Insert->currpos - ((char *) Insert->currpage); } S_UNLOCK(&(XLogCtl->insert_lck)); force_lgwr = true; } - if (force_lgwr || WriteRqst.xlogid > record.xlogid || - (WriteRqst.xlogid == record.xlogid && + if (force_lgwr || WriteRqst.xlogid > record.xlogid || + (WriteRqst.xlogid == record.xlogid && WriteRqst.xrecoff >= record.xrecoff + BLCKSZ)) { if (!TAS(&(XLogCtl->lgwr_lck))) @@ -518,12 +521,12 @@ XLogFlush(XLogRecPtr record) s_lock_sleep(i++); } - if (logFile >= 0 && (LgwrResult.Write.xlogid != logId || - (LgwrResult.Write.xrecoff - 1) / XLogSegSize != logSeg)) + if (logFile >= 0 && (LgwrResult.Write.xlogid != logId || + (LgwrResult.Write.xrecoff - 1) / XLogSegSize != logSeg)) { if (close(logFile) != 0) - elog(STOP, "Close(logfile %u seg %u) failed: %d", - logId, logSeg, errno); + elog(STOP, "Close(logfile %u seg %u) failed: %d", + logId, logSeg, errno); logFile = -1; } @@ -536,11 +539,11 @@ XLogFlush(XLogRecPtr record) } if (fsync(logFile) != 0) - elog(STOP, "Fsync(logfile %u seg %u) failed: %d", - logId, logSeg, errno); + elog(STOP, "Fsync(logfile %u seg %u) failed: %d", + logId, logSeg, errno); LgwrResult.Flush = LgwrResult.Write; - for (i = 0; ; ) + for (i = 0;;) { if (!TAS(&(XLogCtl->info_lck))) { @@ -562,12 +565,12 @@ XLogFlush(XLogRecPtr record) static void GetFreeXLBuffer() { - XLogCtlInsert *Insert = &XLogCtl->Insert; - XLogCtlWrite *Write = &XLogCtl->Write; - uint16 curridx = NextBufIdx(Insert->curridx); + XLogCtlInsert *Insert = &XLogCtl->Insert; + XLogCtlWrite *Write = &XLogCtl->Write; + uint16 curridx = NextBufIdx(Insert->curridx); LgwrRqst.Write = XLogCtl->xlblocks[Insert->curridx]; - for ( ; ; ) + for (;;) { if (!TAS(&(XLogCtl->info_lck))) { @@ -581,6 +584,7 @@ GetFreeXLBuffer() return; } } + /* * LgwrResult lock is busy or un-updated. Try to acquire lgwr lock * and write full blocks. @@ -595,9 +599,10 @@ GetFreeXLBuffer() InitXLBuffer(curridx); return; } - /* - * Have to write buffers while holding insert lock - - * not good... + + /* + * Have to write buffers while holding insert lock - not + * good... */ XLogWrite(NULL); S_UNLOCK(&(XLogCtl->lgwr_lck)); @@ -613,22 +618,22 @@ GetFreeXLBuffer() static void XLogWrite(char *buffer) { - XLogCtlWrite *Write = &XLogCtl->Write; - char *from; - uint32 wcnt = 0; - int i = 0; + XLogCtlWrite *Write = &XLogCtl->Write; + char *from; + uint32 wcnt = 0; + int i = 0; - for ( ; XLByteLT(LgwrResult.Write, LgwrRqst.Write); ) + for (; XLByteLT(LgwrResult.Write, LgwrRqst.Write);) { LgwrResult.Write = XLogCtl->xlblocks[Write->curridx]; - if (LgwrResult.Write.xlogid != logId || + if (LgwrResult.Write.xlogid != logId || (LgwrResult.Write.xrecoff - 1) / XLogSegSize != logSeg) { if (wcnt > 0) { if (fsync(logFile) != 0) - elog(STOP, "Fsync(logfile %u seg %u) failed: %d", - logId, logSeg, errno); + elog(STOP, "Fsync(logfile %u seg %u) failed: %d", + logId, logSeg, errno); if (LgwrResult.Write.xlogid != logId) LgwrResult.Flush.xrecoff = XLogFileSize; else @@ -648,8 +653,8 @@ XLogWrite(char *buffer) if (logFile >= 0) { if (close(logFile) != 0) - elog(STOP, "Close(logfile %u seg %u) failed: %d", - logId, logSeg, errno); + elog(STOP, "Close(logfile %u seg %u) failed: %d", + logId, logSeg, errno); logFile = -1; } logId = LgwrResult.Write.xlogid; @@ -675,9 +680,9 @@ XLogWrite(char *buffer) if (logOff != (LgwrResult.Write.xrecoff - BLCKSZ) % XLogSegSize) { logOff = (LgwrResult.Write.xrecoff - BLCKSZ) % XLogSegSize; - if (lseek(logFile, (off_t)logOff, SEEK_SET) < 0) - elog(STOP, "Lseek(logfile %u seg %u off %u) failed: %d", - logId, logSeg, logOff, errno); + if (lseek(logFile, (off_t) logOff, SEEK_SET) < 0) + elog(STOP, "Lseek(logfile %u seg %u off %u) failed: %d", + logId, logSeg, logOff, errno); } if (buffer != NULL && XLByteLT(LgwrRqst.Write, LgwrResult.Write)) @@ -686,8 +691,8 @@ XLogWrite(char *buffer) from = XLogCtl->pages + Write->curridx * BLCKSZ; if (write(logFile, from, BLCKSZ) != BLCKSZ) - elog(STOP, "Write(logfile %u seg %u off %u) failed: %d", - logId, logSeg, logOff, errno); + elog(STOP, "Write(logfile %u seg %u off %u) failed: %d", + logId, logSeg, logOff, errno); wcnt++; logOff += BLCKSZ; @@ -700,16 +705,16 @@ XLogWrite(char *buffer) if (wcnt == 0) elog(STOP, "XLogWrite: nothing written"); - if (XLByteLT(LgwrResult.Flush, LgwrRqst.Flush) && + if (XLByteLT(LgwrResult.Flush, LgwrRqst.Flush) && XLByteLE(LgwrRqst.Flush, LgwrResult.Write)) { if (fsync(logFile) != 0) - elog(STOP, "Fsync(logfile %u seg %u) failed: %d", - logId, logSeg, errno); + elog(STOP, "Fsync(logfile %u seg %u) failed: %d", + logId, logSeg, errno); LgwrResult.Flush = LgwrResult.Write; } - for ( ; ; ) + for (;;) { if (!TAS(&(XLogCtl->info_lck))) { @@ -727,54 +732,54 @@ XLogWrite(char *buffer) static int XLogFileInit(uint32 log, uint32 seg) { - char path[MAXPGPATH]; - int fd; + char path[MAXPGPATH]; + int fd; XLogFileName(path, log, seg); unlink(path); tryAgain: #ifndef __CYGWIN__ - fd = open(path, O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR); + fd = open(path, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); #else - fd = open(path, O_RDWR|O_CREAT|O_EXCL|O_BINARY, S_IRUSR|S_IWUSR); + fd = open(path, O_RDWR | O_CREAT | O_EXCL | O_BINARY, S_IRUSR | S_IWUSR); #endif if (fd < 0 && (errno == EMFILE || errno == ENFILE)) { fd = errno; if (!ReleaseDataFile()) - elog(STOP, "Create(logfile %u seg %u) failed: %d (and no one data file can be closed)", - logId, logSeg, fd); + elog(STOP, "Create(logfile %u seg %u) failed: %d (and no one data file can be closed)", + logId, logSeg, fd); goto tryAgain; } if (fd < 0) - elog(STOP, "Init(logfile %u seg %u) failed: %d", - logId, logSeg, errno); + elog(STOP, "Init(logfile %u seg %u) failed: %d", + logId, logSeg, errno); if (lseek(fd, XLogSegSize - 1, SEEK_SET) != (off_t) (XLogSegSize - 1)) - elog(STOP, "Lseek(logfile %u seg %u) failed: %d", - logId, logSeg, errno); + elog(STOP, "Lseek(logfile %u seg %u) failed: %d", + logId, logSeg, errno); if (write(fd, "", 1) != 1) - elog(STOP, "Init(logfile %u seg %u) failed: %d", - logId, logSeg, errno); + elog(STOP, "Init(logfile %u seg %u) failed: %d", + logId, logSeg, errno); if (fsync(fd) != 0) - elog(STOP, "Fsync(logfile %u seg %u) failed: %d", - logId, logSeg, errno); + elog(STOP, "Fsync(logfile %u seg %u) failed: %d", + logId, logSeg, errno); if (lseek(fd, 0, SEEK_SET) < 0) - elog(STOP, "Lseek(logfile %u seg %u off %u) failed: %d", - log, seg, 0, errno); + elog(STOP, "Lseek(logfile %u seg %u off %u) failed: %d", + log, seg, 0, errno); - return(fd); + return (fd); } static int XLogFileOpen(uint32 log, uint32 seg, bool econt) { - char path[MAXPGPATH]; - int fd; + char path[MAXPGPATH]; + int fd; XLogFileName(path, log, seg); @@ -788,8 +793,8 @@ tryAgain: { fd = errno; if (!ReleaseDataFile()) - elog(STOP, "Open(logfile %u seg %u) failed: %d (and no one data file can be closed)", - logId, logSeg, fd); + elog(STOP, "Open(logfile %u seg %u) failed: %d (and no one data file can be closed)", + logId, logSeg, fd); goto tryAgain; } if (fd < 0) @@ -797,24 +802,24 @@ tryAgain: if (econt && errno == ENOENT) { elog(LOG, "Open(logfile %u seg %u) failed: file doesn't exist", - logId, logSeg); + logId, logSeg); return (fd); } - elog(STOP, "Open(logfile %u seg %u) failed: %d", - logId, logSeg, errno); + elog(STOP, "Open(logfile %u seg %u) failed: %d", + logId, logSeg, errno); } - return(fd); + return (fd); } -static XLogRecord* +static XLogRecord * ReadRecord(XLogRecPtr *RecPtr, char *buffer) { - XLogRecord *record; - XLogRecPtr tmpRecPtr = EndRecPtr; - bool nextmode = (RecPtr == NULL); - int emode = (nextmode) ? LOG : STOP; - bool noBlck = false; + XLogRecord *record; + XLogRecPtr tmpRecPtr = EndRecPtr; + bool nextmode = (RecPtr == NULL); + int emode = (nextmode) ? LOG : STOP; + bool noBlck = false; if (nextmode) { @@ -835,10 +840,10 @@ ReadRecord(XLogRecPtr *RecPtr, char *buffer) } else if (!XRecOffIsValid(RecPtr->xrecoff)) elog(STOP, "ReadRecord: invalid record offset in (%u, %u)", - RecPtr->xlogid, RecPtr->xrecoff); + RecPtr->xlogid, RecPtr->xrecoff); - if (readFile >= 0 && (RecPtr->xlogid != readId || - RecPtr->xrecoff / XLogSegSize != readSeg)) + if (readFile >= 0 && (RecPtr->xlogid != readId || + RecPtr->xrecoff / XLogSegSize != readSeg)) { close(readFile); readFile = -1; @@ -856,59 +861,59 @@ ReadRecord(XLogRecPtr *RecPtr, char *buffer) if (noBlck || readOff != (RecPtr->xrecoff % XLogSegSize) / BLCKSZ) { readOff = (RecPtr->xrecoff % XLogSegSize) / BLCKSZ; - if (lseek(readFile, (off_t)(readOff * BLCKSZ), SEEK_SET) < 0) - elog(STOP, "ReadRecord: lseek(logfile %u seg %u off %u) failed: %d", - readId, readSeg, readOff, errno); + if (lseek(readFile, (off_t) (readOff * BLCKSZ), SEEK_SET) < 0) + elog(STOP, "ReadRecord: lseek(logfile %u seg %u off %u) failed: %d", + readId, readSeg, readOff, errno); if (read(readFile, readBuf, BLCKSZ) != BLCKSZ) - elog(STOP, "ReadRecord: read(logfile %u seg %u off %u) failed: %d", - readId, readSeg, readOff, errno); - if (((XLogPageHeader)readBuf)->xlp_magic != XLOG_PAGE_MAGIC) + elog(STOP, "ReadRecord: read(logfile %u seg %u off %u) failed: %d", + readId, readSeg, readOff, errno); + if (((XLogPageHeader) readBuf)->xlp_magic != XLOG_PAGE_MAGIC) { elog(emode, "ReadRecord: invalid magic number %u in logfile %u seg %u off %u", - ((XLogPageHeader)readBuf)->xlp_magic, - readId, readSeg, readOff); + ((XLogPageHeader) readBuf)->xlp_magic, + readId, readSeg, readOff); goto next_record_is_invalid; } } - if ((((XLogPageHeader)readBuf)->xlp_info & XLP_FIRST_IS_SUBRECORD) && + if ((((XLogPageHeader) readBuf)->xlp_info & XLP_FIRST_IS_SUBRECORD) && RecPtr->xrecoff % BLCKSZ == SizeOfXLogPHD) { elog(emode, "ReadRecord: subrecord is requested by (%u, %u)", - RecPtr->xlogid, RecPtr->xrecoff); + RecPtr->xlogid, RecPtr->xrecoff); goto next_record_is_invalid; } - record = (XLogRecord*)((char*) readBuf + RecPtr->xrecoff % BLCKSZ); + record = (XLogRecord *) ((char *) readBuf + RecPtr->xrecoff % BLCKSZ); got_record:; - if (record->xl_len == 0 || record->xl_len > + if (record->xl_len == 0 || record->xl_len > (BLCKSZ - RecPtr->xrecoff % BLCKSZ - SizeOfXLogRecord)) { elog(emode, "ReadRecord: invalid record len %u in (%u, %u)", - record->xl_len, RecPtr->xlogid, RecPtr->xrecoff); + record->xl_len, RecPtr->xlogid, RecPtr->xrecoff); goto next_record_is_invalid; } if (record->xl_rmid > RM_MAX_ID) { elog(emode, "ReadRecord: invalid resource managed id %u in (%u, %u)", - record->xl_rmid, RecPtr->xlogid, RecPtr->xrecoff); + record->xl_rmid, RecPtr->xlogid, RecPtr->xrecoff); goto next_record_is_invalid; } nextRecord = NULL; if (record->xl_info & XLR_TO_BE_CONTINUED) { - XLogSubRecord *subrecord; - uint32 len = record->xl_len; + XLogSubRecord *subrecord; + uint32 len = record->xl_len; if (record->xl_len + RecPtr->xrecoff % BLCKSZ + SizeOfXLogRecord != BLCKSZ) { elog(emode, "ReadRecord: invalid fragmented record len %u in (%u, %u)", - record->xl_len, RecPtr->xlogid, RecPtr->xrecoff); + record->xl_len, RecPtr->xlogid, RecPtr->xrecoff); goto next_record_is_invalid; } memcpy(buffer, record, record->xl_len + SizeOfXLogRecord); - record = (XLogRecord*) buffer; + record = (XLogRecord *) buffer; buffer += record->xl_len + SizeOfXLogRecord; - for ( ; ; ) + for (;;) { readOff++; if (readOff == XLogSegSize / BLCKSZ) @@ -926,114 +931,113 @@ got_record:; goto next_record_is_invalid; } if (read(readFile, readBuf, BLCKSZ) != BLCKSZ) - elog(STOP, "ReadRecord: read(logfile %u seg %u off %u) failed: %d", - readId, readSeg, readOff, errno); - if (((XLogPageHeader)readBuf)->xlp_magic != XLOG_PAGE_MAGIC) + elog(STOP, "ReadRecord: read(logfile %u seg %u off %u) failed: %d", + readId, readSeg, readOff, errno); + if (((XLogPageHeader) readBuf)->xlp_magic != XLOG_PAGE_MAGIC) { elog(emode, "ReadRecord: invalid magic number %u in logfile %u seg %u off %u", - ((XLogPageHeader)readBuf)->xlp_magic, - readId, readSeg, readOff); + ((XLogPageHeader) readBuf)->xlp_magic, + readId, readSeg, readOff); goto next_record_is_invalid; } - if (!(((XLogPageHeader)readBuf)->xlp_info & XLP_FIRST_IS_SUBRECORD)) + if (!(((XLogPageHeader) readBuf)->xlp_info & XLP_FIRST_IS_SUBRECORD)) { elog(emode, "ReadRecord: there is no subrecord flag in logfile %u seg %u off %u", - readId, readSeg, readOff); + readId, readSeg, readOff); goto next_record_is_invalid; } - subrecord = (XLogSubRecord*)((char*) readBuf + SizeOfXLogPHD); - if (subrecord->xl_len == 0 || subrecord->xl_len > + subrecord = (XLogSubRecord *) ((char *) readBuf + SizeOfXLogPHD); + if (subrecord->xl_len == 0 || subrecord->xl_len > (BLCKSZ - SizeOfXLogPHD - SizeOfXLogSubRecord)) { elog(emode, "ReadRecord: invalid subrecord len %u in logfile %u seg %u off %u", - subrecord->xl_len, readId, readSeg, readOff); + subrecord->xl_len, readId, readSeg, readOff); goto next_record_is_invalid; } len += subrecord->xl_len; if (len > MAXLOGRECSZ) { elog(emode, "ReadRecord: too long record len %u in (%u, %u)", - len, RecPtr->xlogid, RecPtr->xrecoff); + len, RecPtr->xlogid, RecPtr->xrecoff); goto next_record_is_invalid; } - memcpy(buffer, (char*)subrecord + SizeOfXLogSubRecord, subrecord->xl_len); + memcpy(buffer, (char *) subrecord + SizeOfXLogSubRecord, subrecord->xl_len); buffer += subrecord->xl_len; if (subrecord->xl_info & XLR_TO_BE_CONTINUED) { - if (subrecord->xl_len + + if (subrecord->xl_len + SizeOfXLogPHD + SizeOfXLogSubRecord != BLCKSZ) { elog(emode, "ReadRecord: invalid fragmented subrecord len %u in logfile %u seg %u off %u", - subrecord->xl_len, readId, readSeg, readOff); + subrecord->xl_len, readId, readSeg, readOff); goto next_record_is_invalid; } continue; } break; } - if (BLCKSZ - SizeOfXLogRecord >= + if (BLCKSZ - SizeOfXLogRecord >= subrecord->xl_len + SizeOfXLogPHD + SizeOfXLogSubRecord) { - nextRecord = (XLogRecord*) - ((char*)subrecord + subrecord->xl_len + SizeOfXLogSubRecord); + nextRecord = (XLogRecord *) + ((char *) subrecord + subrecord->xl_len + SizeOfXLogSubRecord); } EndRecPtr.xlogid = readId; - EndRecPtr.xrecoff = readSeg * XLogSegSize + readOff * BLCKSZ + + EndRecPtr.xrecoff = readSeg * XLogSegSize + readOff * BLCKSZ + SizeOfXLogPHD + SizeOfXLogSubRecord + subrecord->xl_len; ReadRecPtr = *RecPtr; - return(record); + return (record); } - if (BLCKSZ - SizeOfXLogRecord >= + if (BLCKSZ - SizeOfXLogRecord >= record->xl_len + RecPtr->xrecoff % BLCKSZ + SizeOfXLogRecord) - { - nextRecord = (XLogRecord*)((char*)record + record->xl_len + SizeOfXLogRecord); - } + nextRecord = (XLogRecord *) ((char *) record + record->xl_len + SizeOfXLogRecord); EndRecPtr.xlogid = RecPtr->xlogid; EndRecPtr.xrecoff = RecPtr->xrecoff + record->xl_len + SizeOfXLogRecord; ReadRecPtr = *RecPtr; - return(record); + return (record); next_record_is_invalid:; close(readFile); readFile = -1; nextRecord = NULL; memset(buffer, 0, SizeOfXLogRecord); - record = (XLogRecord*) buffer; + record = (XLogRecord *) buffer; + /* * If we assumed that next record began on the same page where * previous one ended - zero end of page. */ if (XLByteEQ(tmpRecPtr, EndRecPtr)) { - Assert (EndRecPtr.xrecoff % BLCKSZ > (SizeOfXLogPHD + SizeOfXLogSubRecord) && - BLCKSZ - EndRecPtr.xrecoff % BLCKSZ >= SizeOfXLogRecord); + Assert(EndRecPtr.xrecoff % BLCKSZ > (SizeOfXLogPHD + SizeOfXLogSubRecord) && + BLCKSZ - EndRecPtr.xrecoff % BLCKSZ >= SizeOfXLogRecord); readId = EndRecPtr.xlogid; readSeg = EndRecPtr.xrecoff / XLogSegSize; readOff = (EndRecPtr.xrecoff % XLogSegSize) / BLCKSZ; elog(LOG, "Formatting logfile %u seg %u block %u at offset %u", - readId, readSeg, readOff, EndRecPtr.xrecoff % BLCKSZ); + readId, readSeg, readOff, EndRecPtr.xrecoff % BLCKSZ); readFile = XLogFileOpen(readId, readSeg, false); - if (lseek(readFile, (off_t)(readOff * BLCKSZ), SEEK_SET) < 0) - elog(STOP, "ReadRecord: lseek(logfile %u seg %u off %u) failed: %d", - readId, readSeg, readOff, errno); + if (lseek(readFile, (off_t) (readOff * BLCKSZ), SEEK_SET) < 0) + elog(STOP, "ReadRecord: lseek(logfile %u seg %u off %u) failed: %d", + readId, readSeg, readOff, errno); if (read(readFile, readBuf, BLCKSZ) != BLCKSZ) - elog(STOP, "ReadRecord: read(logfile %u seg %u off %u) failed: %d", - readId, readSeg, readOff, errno); - memset(readBuf + EndRecPtr.xrecoff % BLCKSZ, 0, - BLCKSZ - EndRecPtr.xrecoff % BLCKSZ); - if (lseek(readFile, (off_t)(readOff * BLCKSZ), SEEK_SET) < 0) - elog(STOP, "ReadRecord: lseek(logfile %u seg %u off %u) failed: %d", - readId, readSeg, readOff, errno); + elog(STOP, "ReadRecord: read(logfile %u seg %u off %u) failed: %d", + readId, readSeg, readOff, errno); + memset(readBuf + EndRecPtr.xrecoff % BLCKSZ, 0, + BLCKSZ - EndRecPtr.xrecoff % BLCKSZ); + if (lseek(readFile, (off_t) (readOff * BLCKSZ), SEEK_SET) < 0) + elog(STOP, "ReadRecord: lseek(logfile %u seg %u off %u) failed: %d", + readId, readSeg, readOff, errno); if (write(readFile, readBuf, BLCKSZ) != BLCKSZ) - elog(STOP, "ReadRecord: write(logfile %u seg %u off %u) failed: %d", - readId, readSeg, readOff, errno); + elog(STOP, "ReadRecord: write(logfile %u seg %u off %u) failed: %d", + readId, readSeg, readOff, errno); readOff++; } else { - Assert (EndRecPtr.xrecoff % BLCKSZ == 0 || - BLCKSZ - EndRecPtr.xrecoff % BLCKSZ < SizeOfXLogRecord); + Assert(EndRecPtr.xrecoff % BLCKSZ == 0 || + BLCKSZ - EndRecPtr.xrecoff % BLCKSZ < SizeOfXLogRecord); readId = tmpRecPtr.xlogid; readSeg = tmpRecPtr.xrecoff / XLogSegSize; readOff = (tmpRecPtr.xrecoff % XLogSegSize) / BLCKSZ; @@ -1043,26 +1047,26 @@ next_record_is_invalid:; { if (!XLByteEQ(tmpRecPtr, EndRecPtr)) elog(LOG, "Formatting logfile %u seg %u block %u at offset 0", - readId, readSeg, readOff); + readId, readSeg, readOff); readOff *= BLCKSZ; memset(readBuf, 0, BLCKSZ); readFile = XLogFileOpen(readId, readSeg, false); - if (lseek(readFile, (off_t)readOff, SEEK_SET) < 0) - elog(STOP, "ReadRecord: lseek(logfile %u seg %u off %u) failed: %d", - readId, readSeg, readOff, errno); + if (lseek(readFile, (off_t) readOff, SEEK_SET) < 0) + elog(STOP, "ReadRecord: lseek(logfile %u seg %u off %u) failed: %d", + readId, readSeg, readOff, errno); while (readOff < XLogSegSize) { if (write(readFile, readBuf, BLCKSZ) != BLCKSZ) - elog(STOP, "ReadRecord: write(logfile %u seg %u off %u) failed: %d", - readId, readSeg, readOff, errno); + elog(STOP, "ReadRecord: write(logfile %u seg %u off %u) failed: %d", + readId, readSeg, readOff, errno); readOff += BLCKSZ; } } if (readFile >= 0) { if (fsync(readFile) < 0) - elog(STOP, "ReadRecord: fsync(logfile %u seg %u) failed: %d", - readId, readSeg, errno); + elog(STOP, "ReadRecord: fsync(logfile %u seg %u) failed: %d", + readId, readSeg, errno); close(readFile); readFile = -1; } @@ -1084,19 +1088,19 @@ next_record_is_invalid:; readId++; } { - char path[MAXPGPATH]; + char path[MAXPGPATH]; XLogFileName(path, readId, readSeg); unlink(path); } - return(record); + return (record); } void UpdateControlFile() { - int fd; + int fd; tryAgain: #ifndef __CYGWIN__ @@ -1108,8 +1112,8 @@ tryAgain: { fd = errno; if (!ReleaseDataFile()) - elog(STOP, "Open(cntlfile) failed: %d (and no one data file can be closed)", - fd); + elog(STOP, "Open(cntlfile) failed: %d (and no one data file can be closed)", + fd); goto tryAgain; } if (fd < 0) @@ -1132,23 +1136,23 @@ XLOGShmemSize() if (XLOGbuffers < MinXLOGbuffers) XLOGbuffers = MinXLOGbuffers; - return(sizeof(XLogCtlData) + BLCKSZ * XLOGbuffers + + return (sizeof(XLogCtlData) + BLCKSZ * XLOGbuffers + sizeof(XLogRecPtr) * XLOGbuffers + BLCKSZ); } void XLOGShmemInit(void) { - bool found; + bool found; if (XLOGbuffers < MinXLOGbuffers) XLOGbuffers = MinXLOGbuffers; - ControlFile = (ControlFileData*) + ControlFile = (ControlFileData *) ShmemInitStruct("Control File", BLCKSZ, &found); Assert(!found); - XLogCtl = (XLogCtlData*) - ShmemInitStruct("XLOG Ctl", sizeof(XLogCtlData) + BLCKSZ * XLOGbuffers + + XLogCtl = (XLogCtlData *) + ShmemInitStruct("XLOG Ctl", sizeof(XLogCtlData) + BLCKSZ * XLOGbuffers + sizeof(XLogRecPtr) * XLOGbuffers, &found); Assert(!found); } @@ -1159,43 +1163,45 @@ XLOGShmemInit(void) void BootStrapXLOG() { - int fd; - char buffer[BLCKSZ]; - CheckPoint checkPoint; + int fd; + char buffer[BLCKSZ]; + CheckPoint checkPoint; #ifdef NOT_USED - XLogPageHeader page = (XLogPageHeader)buffer; - XLogRecord *record; + XLogPageHeader page = (XLogPageHeader) buffer; + XLogRecord *record; + #endif #ifndef __CYGWIN__ - fd = open(ControlFilePath, O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR); + fd = open(ControlFilePath, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); #else - fd = open(ControlFilePath, O_RDWR|O_CREAT|O_EXCL|O_BINARY, S_IRUSR|S_IWUSR); + fd = open(ControlFilePath, O_RDWR | O_CREAT | O_EXCL | O_BINARY, S_IRUSR | S_IWUSR); #endif if (fd < 0) - elog(STOP, "BootStrapXLOG failed to create control file (%s): %d", - ControlFilePath, errno); + elog(STOP, "BootStrapXLOG failed to create control file (%s): %d", + ControlFilePath, errno); checkPoint.redo.xlogid = 0; checkPoint.redo.xrecoff = SizeOfXLogPHD; checkPoint.undo = checkPoint.redo; checkPoint.nextXid = FirstTransactionId; - checkPoint.nextOid = BootstrapObjectIdData; + checkPoint.nextOid = BootstrapObjectIdData; #ifdef NOT_USED memset(buffer, 0, BLCKSZ); page->xlp_magic = XLOG_PAGE_MAGIC; page->xlp_info = 0; - record = (XLogRecord*) ((char*)page + SizeOfXLogPHD); - record->xl_prev.xlogid = 0; record->xl_prev.xrecoff = 0; + record = (XLogRecord *) ((char *) page + SizeOfXLogPHD); + record->xl_prev.xlogid = 0; + record->xl_prev.xrecoff = 0; record->xl_xact_prev = record->xl_prev; record->xl_xid = InvalidTransactionId; record->xl_len = sizeof(checkPoint); record->xl_info = 0; record->xl_rmid = RM_XLOG_ID; - memcpy((char*)record + SizeOfXLogRecord, &checkPoint, sizeof(checkPoint)); + memcpy((char *) record + SizeOfXLogRecord, &checkPoint, sizeof(checkPoint)); logFile = XLogFileInit(0, 0); @@ -1211,7 +1217,7 @@ BootStrapXLOG() #endif memset(buffer, 0, BLCKSZ); - ControlFile = (ControlFileData*) buffer; + ControlFile = (ControlFileData *) buffer; ControlFile->logId = 0; ControlFile->logSeg = 1; ControlFile->checkPoint = checkPoint.redo; @@ -1230,16 +1236,16 @@ BootStrapXLOG() close(fd); } -static char* +static char * str_time(time_t tnow) { - char *result = ctime(&tnow); - char *p = strchr(result, '\n'); + char *result = ctime(&tnow); + char *p = strchr(result, '\n'); if (p != NULL) *p = 0; - return(result); + return (result); } /* @@ -1249,21 +1255,22 @@ void StartupXLOG() { #ifdef NOT_USED - XLogCtlInsert *Insert; - CheckPoint checkPoint; - XLogRecPtr RecPtr, - LastRec; - XLogRecord *record; - char buffer[MAXLOGRECSZ+SizeOfXLogRecord]; - int recovery = 0; - bool sie_saved = false; + XLogCtlInsert *Insert; + CheckPoint checkPoint; + XLogRecPtr RecPtr, + LastRec; + XLogRecord *record; + char buffer[MAXLOGRECSZ + SizeOfXLogRecord]; + int recovery = 0; + bool sie_saved = false; + #endif - int fd; + int fd; elog(LOG, "Data Base System is starting up at %s", str_time(time(NULL))); - XLogCtl->xlblocks = (XLogRecPtr*) (((char *)XLogCtl) + sizeof(XLogCtlData)); - XLogCtl->pages = ((char *)XLogCtl->xlblocks + sizeof(XLogRecPtr) * XLOGbuffers); + XLogCtl->xlblocks = (XLogRecPtr *) (((char *) XLogCtl) + sizeof(XLogCtlData)); + XLogCtl->pages = ((char *) XLogCtl->xlblocks + sizeof(XLogRecPtr) * XLOGbuffers); XLogCtl->XLogCacheByte = BLCKSZ * XLOGbuffers; XLogCtl->XLogCacheBlck = XLOGbuffers - 1; memset(XLogCtl->xlblocks, 0, sizeof(XLogRecPtr) * XLOGbuffers); @@ -1291,8 +1298,8 @@ tryAgain: { fd = errno; if (!ReleaseDataFile()) - elog(STOP, "Open(\"%s\") failed: %d (and no one data file can be closed)", - ControlFilePath, fd); + elog(STOP, "Open(\"%s\") failed: %d (and no one data file can be closed)", + ControlFilePath, fd); goto tryAgain; } if (fd < 0) @@ -1303,10 +1310,10 @@ tryAgain: close(fd); - if (ControlFile->logSeg == 0 || - ControlFile->time <= 0 || - ControlFile->state < DB_SHUTDOWNED || - ControlFile->state > DB_IN_PRODUCTION || + if (ControlFile->logSeg == 0 || + ControlFile->time <= 0 || + ControlFile->state < DB_SHUTDOWNED || + ControlFile->state > DB_IN_PRODUCTION || !XRecOffIsValid(ControlFile->checkPoint.xrecoff)) elog(STOP, "Control file context is broken"); @@ -1323,20 +1330,20 @@ tryAgain: if (ControlFile->state == DB_SHUTDOWNED) elog(LOG, "Data Base System was shut down at %s", - str_time(ControlFile->time)); + str_time(ControlFile->time)); else if (ControlFile->state == DB_SHUTDOWNING) elog(LOG, "Data Base System was interrupted when shutting down at %s", - str_time(ControlFile->time)); + str_time(ControlFile->time)); else if (ControlFile->state == DB_IN_RECOVERY) { elog(LOG, "Data Base System was interrupted being in recovery at %s\n" - "\tThis propably means that some data blocks are corrupted\n" - "\tAnd you will have to use last backup for recovery", - str_time(ControlFile->time)); + "\tThis propably means that some data blocks are corrupted\n" + "\tAnd you will have to use last backup for recovery", + str_time(ControlFile->time)); } else if (ControlFile->state == DB_IN_PRODUCTION) elog(LOG, "Data Base System was interrupted being in production at %s", - str_time(ControlFile->time)); + str_time(ControlFile->time)); #ifdef NOT_USED @@ -1350,14 +1357,14 @@ tryAgain: elog(STOP, "Invalid RMID in checkPoint record"); if (record->xl_len != sizeof(checkPoint)) elog(STOP, "Invalid length of checkPoint record"); - checkPoint = *((CheckPoint*)((char*)record + SizeOfXLogRecord)); + checkPoint = *((CheckPoint *) ((char *) record + SizeOfXLogRecord)); elog(LOG, "Redo record at (%u, %u); Undo record at (%u, %u)", - checkPoint.redo.xlogid, checkPoint.redo.xrecoff, - checkPoint.undo.xlogid, checkPoint.undo.xrecoff); + checkPoint.redo.xlogid, checkPoint.redo.xrecoff, + checkPoint.undo.xlogid, checkPoint.undo.xrecoff); elog(LOG, "NextTransactionId: %u; NextOid: %u", - checkPoint.nextXid, checkPoint.nextOid); - if (checkPoint.nextXid < FirstTransactionId || + checkPoint.nextXid, checkPoint.nextOid); + if (checkPoint.nextXid < FirstTransactionId || checkPoint.nextOid < BootstrapObjectIdData) #ifdef XLOG elog(STOP, "Invalid NextTransactionId/NextOid"); @@ -1389,7 +1396,7 @@ tryAgain: if (recovery > 0) { elog(LOG, "The DataBase system was not properly shut down\n" - "\tAutomatic recovery is in progress..."); + "\tAutomatic recovery is in progress..."); ControlFile->state = DB_IN_RECOVERY; ControlFile->time = time(NULL); UpdateControlFile(); @@ -1400,14 +1407,15 @@ tryAgain: /* Is REDO required ? */ if (XLByteLT(checkPoint.redo, RecPtr)) record = ReadRecord(&(checkPoint.redo), buffer); - else /* read past CheckPoint record */ + else +/* read past CheckPoint record */ record = ReadRecord(NULL, buffer); /* REDO */ if (record->xl_len != 0) { - elog(LOG, "Redo starts at (%u, %u)", - ReadRecPtr.xlogid, ReadRecPtr.xrecoff); + elog(LOG, "Redo starts at (%u, %u)", + ReadRecPtr.xlogid, ReadRecPtr.xrecoff); do { #ifdef XLOG @@ -1417,8 +1425,8 @@ tryAgain: RmgrTable[record->xl_rmid].rm_redo(EndRecPtr, record); record = ReadRecord(NULL, buffer); } while (record->xl_len != 0); - elog(LOG, "Redo done at (%u, %u)", - ReadRecPtr.xlogid, ReadRecPtr.xrecoff); + elog(LOG, "Redo done at (%u, %u)", + ReadRecPtr.xlogid, ReadRecPtr.xrecoff); LastRec = ReadRecPtr; } else @@ -1431,18 +1439,18 @@ tryAgain: RecPtr = ReadRecPtr; if (XLByteLT(checkPoint.undo, RecPtr)) { - elog(LOG, "Undo starts at (%u, %u)", - RecPtr.xlogid, RecPtr.xrecoff); + elog(LOG, "Undo starts at (%u, %u)", + RecPtr.xlogid, RecPtr.xrecoff); do { record = ReadRecord(&RecPtr, buffer); - if (TransactionIdIsValid(record->xl_xid) && + if (TransactionIdIsValid(record->xl_xid) && !TransactionIdDidCommit(record->xl_xid)) RmgrTable[record->xl_rmid].rm_undo(record); RecPtr = record->xl_prev; } while (XLByteLE(checkPoint.undo, RecPtr)); - elog(LOG, "Undo done at (%u, %u)", - ReadRecPtr.xlogid, ReadRecPtr.xrecoff); + elog(LOG, "Undo done at (%u, %u)", + ReadRecPtr.xlogid, ReadRecPtr.xrecoff); } else { @@ -1458,19 +1466,19 @@ tryAgain: logOff = 0; logFile = XLogFileOpen(logId, logSeg, false); XLogCtl->xlblocks[0].xlogid = logId; - XLogCtl->xlblocks[0].xrecoff = - ((EndRecPtr.xrecoff - 1) / BLCKSZ + 1) * BLCKSZ; + XLogCtl->xlblocks[0].xrecoff = + ((EndRecPtr.xrecoff - 1) / BLCKSZ + 1) * BLCKSZ; Insert = &XLogCtl->Insert; - memcpy((char*)(Insert->currpage), readBuf, BLCKSZ); - Insert->currpos = ((char*) Insert->currpage) + + memcpy((char *) (Insert->currpage), readBuf, BLCKSZ); + Insert->currpos = ((char *) Insert->currpage) + (EndRecPtr.xrecoff + BLCKSZ - XLogCtl->xlblocks[0].xrecoff); Insert->PrevRecord = ControlFile->checkPoint; if (recovery > 0) { - int i; + int i; - /* + /* * Let resource managers know that recovery is done */ for (i = 0; i <= RM_MAX_ID; i++) @@ -1479,7 +1487,7 @@ tryAgain: StopIfError = sie_saved; } -#endif /* NOT_USED */ +#endif /* NOT_USED */ ControlFile->state = DB_IN_PRODUCTION; ControlFile->time = time(NULL); @@ -1508,11 +1516,11 @@ void CreateCheckPoint(bool shutdown) { #ifdef NOT_USED - CheckPoint checkPoint; - XLogRecPtr recptr; - XLogCtlInsert *Insert = &XLogCtl->Insert; - uint32 freespace; - uint16 curridx; + CheckPoint checkPoint; + XLogRecPtr recptr; + XLogCtlInsert *Insert = &XLogCtl->Insert; + uint32 freespace; + uint16 curridx; memset(&checkPoint, 0, sizeof(checkPoint)); if (shutdown) @@ -1531,21 +1539,21 @@ CreateCheckPoint(bool shutdown) elog(STOP, "XLog insert lock is busy while data base is shutting down"); (void) select(0, NULL, NULL, NULL, &delay); } - freespace = ((char*) Insert->currpage) + BLCKSZ - Insert->currpos; + freespace = ((char *) Insert->currpage) + BLCKSZ - Insert->currpos; if (freespace < SizeOfXLogRecord) { curridx = NextBufIdx(Insert->curridx); if (XLByteLE(XLogCtl->xlblocks[curridx], LgwrResult.Write)) InitXLBuffer(curridx); - else + else GetFreeXLBuffer(); freespace = BLCKSZ - SizeOfXLogPHD; } else curridx = Insert->curridx; checkPoint.redo.xlogid = XLogCtl->xlblocks[curridx].xlogid; - checkPoint.redo.xrecoff = XLogCtl->xlblocks[curridx].xrecoff - BLCKSZ + - Insert->currpos - ((char*) Insert->currpage); + checkPoint.redo.xrecoff = XLogCtl->xlblocks[curridx].xrecoff - BLCKSZ + + Insert->currpos - ((char *) Insert->currpage); S_UNLOCK(&(XLogCtl->insert_lck)); SpinAcquire(XidGenLockId); @@ -1563,14 +1571,14 @@ CreateCheckPoint(bool shutdown) if (shutdown && checkPoint.undo.xrecoff != 0) elog(STOP, "Active transaction while data base is shutting down"); - recptr = XLogInsert(RM_XLOG_ID, (char*)&checkPoint, sizeof(checkPoint), NULL, 0); + recptr = XLogInsert(RM_XLOG_ID, (char *) &checkPoint, sizeof(checkPoint), NULL, 0); if (shutdown && !XLByteEQ(checkPoint.redo, MyLastRecPtr)) elog(STOP, "XLog concurrent activity while data base is shutting down"); XLogFlush(recptr); -#endif /* NOT_USED */ +#endif /* NOT_USED */ SpinAcquire(ControlFileLockId); if (shutdown) diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c index 8e129a460a9..a12bca94932 100644 --- a/src/backend/bootstrap/bootstrap.c +++ b/src/backend/bootstrap/bootstrap.c @@ -8,7 +8,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.80 2000/02/18 09:28:39 inoue Exp $ + * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.81 2000/04/12 17:14:54 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -39,13 +39,13 @@ #define ALLOC(t, c) (t *)calloc((unsigned)(c), sizeof(t)) -extern void BaseInit(void); -extern void StartupXLOG(void); -extern void ShutdownXLOG(void); -extern void BootStrapXLOG(void); +extern void BaseInit(void); +extern void StartupXLOG(void); +extern void ShutdownXLOG(void); +extern void BootStrapXLOG(void); -extern char XLogDir[]; -extern char ControlFilePath[]; +extern char XLogDir[]; +extern char ControlFilePath[]; extern int Int_yyparse(void); static hashnode *AddStr(char *str, int strlength, int mderef); @@ -107,7 +107,7 @@ static struct typinfo Procid[] = { {"char", CHAROID, 0, 1, F_CHARIN, F_CHAROUT}, {"name", NAMEOID, 0, NAMEDATALEN, F_NAMEIN, F_NAMEOUT}, {"int2", INT2OID, 0, 2, F_INT2IN, F_INT2OUT}, - {"int2vector", INT2VECTOROID, 0, INDEX_MAX_KEYS*2, F_INT2VECTORIN, F_INT2VECTOROUT}, + {"int2vector", INT2VECTOROID, 0, INDEX_MAX_KEYS * 2, F_INT2VECTORIN, F_INT2VECTOROUT}, {"int4", INT4OID, 0, 4, F_INT4IN, F_INT4OUT}, {"regproc", REGPROCOID, 0, 4, F_REGPROCIN, F_REGPROCOUT}, {"text", TEXTOID, 0, -1, F_TEXTIN, F_TEXTOUT}, @@ -115,7 +115,7 @@ static struct typinfo Procid[] = { {"tid", TIDOID, 0, 6, F_TIDIN, F_TIDOUT}, {"xid", XIDOID, 0, 4, F_XIDIN, F_XIDOUT}, {"cid", CIDOID, 0, 4, F_CIDIN, F_CIDOUT}, - {"oidvector", 30, 0, INDEX_MAX_KEYS*4, F_OIDVECTORIN, F_OIDVECTOROUT}, + {"oidvector", 30, 0, INDEX_MAX_KEYS * 4, F_OIDVECTORIN, F_OIDVECTOROUT}, {"smgr", 210, 0, 2, F_SMGRIN, F_SMGROUT}, {"_int4", 1007, INT4OID, -1, F_ARRAY_IN, F_ARRAY_OUT}, {"_aclitem", 1034, 1033, -1, F_ARRAY_IN, F_ARRAY_OUT} @@ -325,8 +325,8 @@ BootstrapMain(int argc, char *argv[]) } /* - * Bootstrap under Postmaster means two things: - * (xloginit) ? StartupXLOG : ShutdownXLOG + * Bootstrap under Postmaster means two things: (xloginit) ? + * StartupXLOG : ShutdownXLOG * * If !under Postmaster and xloginit then BootStrapXLOG. */ @@ -345,9 +345,7 @@ BootstrapMain(int argc, char *argv[]) } if (!IsUnderPostmaster && xloginit) - { BootStrapXLOG(); - } /* * backend initialization @@ -478,7 +476,7 @@ boot_openrel(char *relname) */ if (namestrcmp(&attrtypes[i]->attname, "attisset") == 0) attrtypes[i]->attisset = get_attisset(RelationGetRelid(reldesc), - NameStr(attrtypes[i]->attname)); + NameStr(attrtypes[i]->attname)); else attrtypes[i]->attisset = false; @@ -1153,8 +1151,10 @@ build_indices() index_build(heap, ind, ILHead->il_natts, ILHead->il_attnos, ILHead->il_nparams, ILHead->il_params, ILHead->il_finfo, ILHead->il_predInfo); - /* In normal processing mode, index_build would close the heap - * and index, but in bootstrap mode it will not. + + /* + * In normal processing mode, index_build would close the heap and + * index, but in bootstrap mode it will not. */ /* diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c index e3fec88e97e..c342b067ff4 100644 --- a/src/backend/catalog/aclchk.c +++ b/src/backend/catalog/aclchk.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.37 2000/01/26 05:56:09 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.38 2000/04/12 17:14:55 momjian Exp $ * * NOTES * See acl.h. @@ -364,7 +364,7 @@ pg_aclcheck(char *relname, char *usename, AclMode mode) */ if (((mode & ACL_WR) || (mode & ACL_AP)) && !allowSystemTableMods && IsSystemRelationName(relname) && - strncmp(relname,"pg_temp.", strlen("pg_temp.")) != 0 && + strncmp(relname, "pg_temp.", strlen("pg_temp.")) != 0 && !((Form_pg_shadow) GETSTRUCT(tuple))->usecatupd) { elog(DEBUG, "pg_aclcheck: catalog update to \"%s\": permission denied", diff --git a/src/backend/catalog/catalog.c b/src/backend/catalog/catalog.c index 5425387b3fe..4a5b1d9df2a 100644 --- a/src/backend/catalog/catalog.c +++ b/src/backend/catalog/catalog.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/catalog.c,v 1.31 2000/04/09 04:43:15 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/catalog.c,v 1.32 2000/04/12 17:14:55 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -44,6 +44,7 @@ relpath(const char *relname) snprintf(path, bufsize, "%s%c%s", DataDir, SEP_CHAR, relname); return path; } + /* * If it is in the current database, assume it is in current working * directory. NB: this does not work during bootstrap! @@ -55,7 +56,7 @@ relpath(const char *relname) * relpath_blind - construct path to a relation's file * * Construct the path using only the info available to smgrblindwrt, - * namely the names and OIDs of the database and relation. (Shared system + * namely the names and OIDs of the database and relation. (Shared system * relations are identified with dbid = 0.) Note that we may have to * access a relation belonging to a different database! * diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index ae8d32bb8d5..b7c56d5eb63 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.124 2000/03/17 02:36:05 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.125 2000/04/12 17:14:55 momjian Exp $ * * * INTERFACE ROUTINES @@ -69,9 +69,9 @@ static void AddNewRelationTuple(Relation pg_class_desc, - Relation new_rel_desc, Oid new_rel_oid, - int natts, - char relkind, char *temp_relname); + Relation new_rel_desc, Oid new_rel_oid, + int natts, + char relkind, char *temp_relname); static void AddToNoNameRelList(Relation r); static void DeleteAttributeTuples(Relation rel); @@ -82,7 +82,7 @@ static void RelationRemoveInheritance(Relation relation); static void RemoveFromNoNameRelList(Relation r); static void AddNewRelationType(char *typeName, Oid new_rel_oid); static void StoreAttrDefault(Relation rel, AttrNumber attnum, char *adbin, - bool updatePgAttribute); + bool updatePgAttribute); static void StoreRelCheck(Relation rel, char *ccname, char *ccbin); static void StoreConstraints(Relation rel); static void RemoveConstraints(Relation rel); @@ -271,8 +271,9 @@ heap_create(char *relname, rel = (Relation) palloc(len); MemSet((char *) rel, 0, len); - rel->rd_fd = -1; /* table is not open */ + rel->rd_fd = -1; /* table is not open */ rel->rd_unlinked = TRUE; /* table is not created yet */ + /* * create a new tuple descriptor from the one passed in */ @@ -345,7 +346,7 @@ heap_create(char *relname, bool heap_storage_create(Relation rel) { - bool smgrcall = false; + bool smgrcall = false; if (rel->rd_unlinked) { @@ -715,6 +716,7 @@ AddNewRelationTuple(Relation pg_class_desc, if (!IsIgnoringSystemIndexes()) { + /* * First, open the catalog indices and insert index tuples for the * new relation. @@ -878,7 +880,7 @@ heap_create_with_catalog(char *relname, * SOMEDAY: fill the STATISTIC relation properly. * ---------------- */ - heap_close(new_rel_desc, NoLock); /* do not unlock till end of xact */ + heap_close(new_rel_desc, NoLock); /* do not unlock till end of xact */ heap_close(pg_class_desc, RowExclusiveLock); return new_rel_oid; @@ -893,7 +895,7 @@ heap_create_with_catalog(char *relname, * 3) remove indexes * 4) remove pg_class tuple * 5) remove pg_attribute tuples and related descriptions - * 6) remove pg_description tuples + * 6) remove pg_description tuples * 7) remove pg_type tuples * 8) RemoveConstraints () * 9) unlink relation @@ -963,7 +965,7 @@ RelationRemoveInheritance(Relation relation) tuple = heap_getnext(scan, 0); if (HeapTupleIsValid(tuple)) { - Oid subclass = ((Form_pg_inherits) GETSTRUCT(tuple))->inhrelid; + Oid subclass = ((Form_pg_inherits) GETSTRUCT(tuple))->inhrelid; heap_endscan(scan); heap_close(catalogRelation, RowExclusiveLock); @@ -1073,7 +1075,7 @@ DeleteRelationTuple(Relation rel) { heap_close(pg_class_desc, RowExclusiveLock); elog(ERROR, "Relation '%s' does not exist", - RelationGetRelationName(rel)); + RelationGetRelationName(rel)); } /* ---------------- @@ -1096,19 +1098,27 @@ DeleteRelationTuple(Relation rel) static void RelationTruncateIndexes(Relation heapRelation) { - Relation indexRelation, currentIndex; + Relation indexRelation, + currentIndex; ScanKeyData entry; HeapScanDesc scan; - HeapTuple indexTuple, procTuple, classTuple; + HeapTuple indexTuple, + procTuple, + classTuple; Form_pg_index index; - Oid heapId, indexId, procId, accessMethodId; - Node *oldPred = NULL; - PredInfo *predInfo; - List *cnfPred = NULL; + Oid heapId, + indexId, + procId, + accessMethodId; + Node *oldPred = NULL; + PredInfo *predInfo; + List *cnfPred = NULL; AttrNumber *attributeNumberA; - FuncIndexInfo fInfo, *funcInfo = NULL; - int i, numberOfAttributes; - char *predString; + FuncIndexInfo fInfo, + *funcInfo = NULL; + int i, + numberOfAttributes; + char *predString; heapId = RelationGetRelid(heapRelation); @@ -1120,8 +1130,10 @@ RelationTruncateIndexes(Relation heapRelation) scan = heap_beginscan(indexRelation, false, SnapshotNow, 1, &entry); while (HeapTupleIsValid(indexTuple = heap_getnext(scan, 0))) { + /* - * For each index, fetch index attributes so we can apply index_build + * For each index, fetch index attributes so we can apply + * index_build */ index = (Form_pg_index) GETSTRUCT(indexTuple); indexId = index->indexrelid; @@ -1181,8 +1193,8 @@ RelationTruncateIndexes(Relation heapRelation) LockRelation(currentIndex, AccessExclusiveLock); /* - * Release any buffers associated with this index. If they're dirty, - * they're just dropped without bothering to flush to disk. + * Release any buffers associated with this index. If they're + * dirty, they're just dropped without bothering to flush to disk. */ ReleaseRelationBuffers(currentIndex); if (FlushRelationBuffers(currentIndex, (BlockNumber) 0, false) < 0) @@ -1198,35 +1210,35 @@ RelationTruncateIndexes(Relation heapRelation) attributeNumberA, 0, NULL, funcInfo, predInfo); /* - * index_build will close both the heap and index relations - * (but not give up the locks we hold on them). That's fine - * for the index, but we need to open the heap again. We need - * no new lock, since this backend still has the exclusive lock - * grabbed by heap_truncate. + * index_build will close both the heap and index relations (but + * not give up the locks we hold on them). That's fine for the + * index, but we need to open the heap again. We need no new + * lock, since this backend still has the exclusive lock grabbed + * by heap_truncate. */ heapRelation = heap_open(heapId, NoLock); Assert(heapRelation != NULL); } /* Complete the scan and close pg_index */ - heap_endscan(scan); + heap_endscan(scan); heap_close(indexRelation, AccessShareLock); } /* ---------------------------- - * heap_truncate + * heap_truncate * - * This routine is used to truncate the data from the - * storage manager of any data within the relation handed - * to this routine. + * This routine is used to truncate the data from the + * storage manager of any data within the relation handed + * to this routine. * ---------------------------- */ void heap_truncate(char *relname) { - Relation rel; - Oid rid; + Relation rel; + Oid rid; /* Open relation for processing, and grab exclusive access on it. */ @@ -1245,12 +1257,12 @@ heap_truncate(char *relname) * they don't exist anyway. So, no warning in that case. * ---------------- */ - if (IsTransactionBlock() && ! rel->rd_myxactonly) + if (IsTransactionBlock() && !rel->rd_myxactonly) elog(NOTICE, "Caution: TRUNCATE TABLE cannot be rolled back, so don't abort now"); /* - * Release any buffers associated with this relation. If they're dirty, - * they're just dropped without bothering to flush to disk. + * Release any buffers associated with this relation. If they're + * dirty, they're just dropped without bothering to flush to disk. */ ReleaseRelationBuffers(rel); @@ -1300,17 +1312,17 @@ DeleteAttributeTuples(Relation rel) attnum++) { if (HeapTupleIsValid(tup = SearchSysCacheTupleCopy(ATTNUM, - ObjectIdGetDatum(RelationGetRelid(rel)), - Int16GetDatum(attnum), + ObjectIdGetDatum(RelationGetRelid(rel)), + Int16GetDatum(attnum), 0, 0))) { - - /*** Delete any comments associated with this attribute ***/ - DeleteComments(tup->t_data->t_oid); + /*** Delete any comments associated with this attribute ***/ + + DeleteComments(tup->t_data->t_oid); - heap_delete(pg_attribute_desc, &tup->t_self, NULL); - heap_freetuple(tup); + heap_delete(pg_attribute_desc, &tup->t_self, NULL); + heap_freetuple(tup); } } @@ -1429,7 +1441,7 @@ DeleteTypeTuple(Relation rel) * we release the read lock on pg_type. -mer 13 Aug 1991 * ---------------- */ - + heap_delete(pg_type_desc, &tup->t_self, NULL); heap_endscan(pg_type_scan); @@ -1477,7 +1489,7 @@ heap_drop_with_catalog(const char *relname) * they don't exist anyway. So, no warning in that case. * ---------------- */ - if (IsTransactionBlock() && ! rel->rd_myxactonly) + if (IsTransactionBlock() && !rel->rd_myxactonly) elog(NOTICE, "Caution: DROP TABLE cannot be rolled back, so don't abort now"); /* ---------------- @@ -1547,8 +1559,8 @@ heap_drop_with_catalog(const char *relname) /* * Close relcache entry, but *keep* AccessExclusiveLock on the - * relation until transaction commit. This ensures no one else - * will try to do something with the doomed relation. + * relation until transaction commit. This ensures no one else will + * try to do something with the doomed relation. */ heap_close(rel, NoLock); @@ -1704,7 +1716,7 @@ StoreAttrDefault(Relation rel, AttrNumber attnum, char *adbin, Relation idescs[Num_pg_attrdef_indices]; HeapTuple tuple; Datum values[4]; - static char nulls[4] = {' ', ' ', ' ', ' '}; + static char nulls[4] = {' ', ' ', ' ', ' '}; Relation attrrel; Relation attridescs[Num_pg_attr_indices]; HeapTuple atttup; @@ -1714,6 +1726,7 @@ StoreAttrDefault(Relation rel, AttrNumber attnum, char *adbin, * Need to construct source equivalent of given node-string. */ expr = stringToNode(adbin); + /* * deparse_expression needs a RangeTblEntry list, so make one */ @@ -1747,18 +1760,18 @@ StoreAttrDefault(Relation rel, AttrNumber attnum, char *adbin, heap_freetuple(tuple); pfree(adsrc); - if (! updatePgAttribute) + if (!updatePgAttribute) return; /* done if pg_attribute is OK */ attrrel = heap_openr(AttributeRelationName, RowExclusiveLock); atttup = SearchSysCacheTupleCopy(ATTNUM, - ObjectIdGetDatum(RelationGetRelid(rel)), + ObjectIdGetDatum(RelationGetRelid(rel)), (Datum) attnum, 0, 0); if (!HeapTupleIsValid(atttup)) elog(ERROR, "cache lookup of attribute %d in relation %u failed", attnum, RelationGetRelid(rel)); attStruct = (Form_pg_attribute) GETSTRUCT(atttup); - if (! attStruct->atthasdef) + if (!attStruct->atthasdef) { attStruct->atthasdef = true; heap_update(attrrel, &atttup->t_self, atttup, NULL); @@ -1789,13 +1802,14 @@ StoreRelCheck(Relation rel, char *ccname, char *ccbin) Relation idescs[Num_pg_relcheck_indices]; HeapTuple tuple; Datum values[4]; - static char nulls[4] = {' ', ' ', ' ', ' '}; + static char nulls[4] = {' ', ' ', ' ', ' '}; /* * Convert condition to a normal boolean expression tree. */ expr = stringToNode(ccbin); expr = (Node *) make_ands_explicit((List *) expr); + /* * deparse_expression needs a RangeTblEntry list, so make one */ @@ -1850,9 +1864,10 @@ StoreConstraints(Relation rel) if (!constr) return; - /* deparsing of constraint expressions will fail unless the just-created - * pg_attribute tuples for this relation are made visible. So, bump - * the command counter. + /* + * deparsing of constraint expressions will fail unless the + * just-created pg_attribute tuples for this relation are made + * visible. So, bump the command counter. */ CommandCounterIncrement(); @@ -1882,7 +1897,7 @@ StoreConstraints(Relation rel) * expression. * * NB: caller should have opened rel with AccessExclusiveLock, and should - * hold that lock till end of transaction. Also, we assume the caller has + * hold that lock till end of transaction. Also, we assume the caller has * done a CommandCounterIncrement if necessary to make the relation's catalog * tuples visible. */ @@ -1921,8 +1936,8 @@ AddRelationRawConstraints(Relation rel, } /* - * Create a dummy ParseState and insert the target relation as - * its sole rangetable entry. We need a ParseState for transformExpr. + * Create a dummy ParseState and insert the target relation as its + * sole rangetable entry. We need a ParseState for transformExpr. */ pstate = make_parsestate(NULL); makeRangeTable(pstate, NULL); @@ -1938,25 +1953,28 @@ AddRelationRawConstraints(Relation rel, Oid type_id; Assert(colDef->raw_default != NULL); + /* * Transform raw parsetree to executable expression. */ expr = transformExpr(pstate, colDef->raw_default, EXPR_COLUMN_FIRST); + /* * Make sure default expr does not refer to any vars. */ if (contain_var_clause(expr)) elog(ERROR, "Cannot use attribute(s) in DEFAULT clause"); + /* - * Check that it will be possible to coerce the expression - * to the column's type. We store the expression without - * coercion, however, to avoid premature coercion in cases like + * Check that it will be possible to coerce the expression to the + * column's type. We store the expression without coercion, + * however, to avoid premature coercion in cases like * * CREATE TABLE tbl (fld datetime DEFAULT 'now'); * - * NB: this should match the code in updateTargetListEntry() - * that will actually do the coercion, to ensure we don't accept - * an unusable default expression. + * NB: this should match the code in updateTargetListEntry() that + * will actually do the coercion, to ensure we don't accept an + * unusable default expression. */ type_id = exprType(expr); if (type_id != InvalidOid) @@ -1966,23 +1984,26 @@ AddRelationRawConstraints(Relation rel, if (type_id != atp->atttypid) { if (CoerceTargetExpr(NULL, expr, type_id, - atp->atttypid, atp->atttypmod) == NULL) + atp->atttypid, atp->atttypmod) == NULL) elog(ERROR, "Attribute '%s' is of type '%s'" " but default expression is of type '%s'" - "\n\tYou will need to rewrite or cast the expression", + "\n\tYou will need to rewrite or cast the expression", NameStr(atp->attname), typeidTypeName(atp->atttypid), typeidTypeName(type_id)); } } + /* * Might as well try to reduce any constant expressions. */ expr = eval_const_expressions(expr); + /* * Must fix opids, in case any operators remain... */ fix_opids(expr); + /* * OK, store it. */ @@ -2037,26 +2058,31 @@ AddRelationRawConstraints(Relation rel, ccname = (char *) palloc(NAMEDATALEN); snprintf(ccname, NAMEDATALEN, "$%d", numchecks + 1); } + /* * Transform raw parsetree to executable expression. */ expr = transformExpr(pstate, cdef->raw_expr, EXPR_COLUMN_FIRST); + /* * Make sure it yields a boolean result. */ if (exprType(expr) != BOOLOID) elog(ERROR, "CHECK '%s' does not yield boolean result", ccname); + /* * Make sure no outside relations are referred to. */ if (length(pstate->p_rtable) != 1) elog(ERROR, "Only relation '%s' can be referenced in CHECK", relname); + /* * Might as well try to reduce any constant expressions. */ expr = eval_const_expressions(expr); + /* * Constraints are evaluated with execQual, which expects an * implicit-AND list, so convert expression to implicit-AND form. @@ -2064,10 +2090,12 @@ AddRelationRawConstraints(Relation rel, * overkill...) */ expr = (Node *) make_ands_implicit((Expr *) expr); + /* * Must fix opids in operator clauses. */ fix_opids(expr); + /* * OK, store it. */ @@ -2081,12 +2109,12 @@ AddRelationRawConstraints(Relation rel, * We do this even if there was no change, in order to ensure that an * SI update message is sent out for the pg_class tuple, which will * force other backends to rebuild their relcache entries for the rel. - * (Of course, for a newly created rel there is no need for an SI message, - * but for ALTER TABLE ADD ATTRIBUTE this'd be important.) + * (Of course, for a newly created rel there is no need for an SI + * message, but for ALTER TABLE ADD ATTRIBUTE this'd be important.) */ relrel = heap_openr(RelationRelationName, RowExclusiveLock); reltup = SearchSysCacheTupleCopy(RELOID, - ObjectIdGetDatum(RelationGetRelid(rel)), + ObjectIdGetDatum(RelationGetRelid(rel)), 0, 0, 0); if (!HeapTupleIsValid(reltup)) elog(ERROR, "cache lookup of relation %u failed", RelationGetRelid(rel)); diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 2a4cd3e6c5e..a8c649bc82d 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.107 2000/03/01 05:39:24 inoue Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.108 2000/04/12 17:14:55 momjian Exp $ * * * INTERFACE ROUTINES @@ -56,37 +56,41 @@ /* non-export function prototypes */ static Oid GetHeapRelationOid(char *heapRelationName, char *indexRelationName, - bool istemp); + bool istemp); static TupleDesc BuildFuncTupleDesc(FuncIndexInfo *funcInfo); static TupleDesc ConstructTupleDescriptor(Oid heapoid, Relation heapRelation, - List *attributeList, int numatts, AttrNumber *attNums); + List *attributeList, int numatts, AttrNumber *attNums); static void ConstructIndexReldesc(Relation indexRelation, Oid amoid); static Oid UpdateRelationRelation(Relation indexRelation, char *temp_relname); static void InitializeAttributeOids(Relation indexRelation, - int numatts, Oid indexoid); + int numatts, Oid indexoid); static void AppendAttributeTuples(Relation indexRelation, int numatts); static void UpdateIndexRelation(Oid indexoid, Oid heapoid, - FuncIndexInfo *funcInfo, int natts, - AttrNumber *attNums, Oid *classOids, Node *predicate, - List *attributeList, bool islossy, bool unique, bool primary); + FuncIndexInfo *funcInfo, int natts, + AttrNumber *attNums, Oid *classOids, Node *predicate, + List *attributeList, bool islossy, bool unique, bool primary); static void DefaultBuild(Relation heapRelation, Relation indexRelation, - int numberOfAttributes, AttrNumber *attributeNumber, - IndexStrategy indexStrategy, uint16 parameterCount, + int numberOfAttributes, AttrNumber *attributeNumber, + IndexStrategy indexStrategy, uint16 parameterCount, Datum *parameter, FuncIndexInfoPtr funcInfo, PredInfo *predInfo); -static Oid IndexGetRelation(Oid indexId); +static Oid IndexGetRelation(Oid indexId); -static bool reindexing = false; -extern bool SetReindexProcessing(bool reindexmode) +static bool reindexing = false; +extern bool +SetReindexProcessing(bool reindexmode) { - bool old = reindexing; + bool old = reindexing; + reindexing = reindexmode; return old; } -extern bool IsReindexProcessing(void) +extern bool +IsReindexProcessing(void) { return reindexing; } + /* ---------------------------------------------------------------- * sysatts is a structure containing attribute tuple forms * for system attributes (numbered -1, -2, ...). This really @@ -1011,7 +1015,7 @@ index_create(char *heapRelationName, * ---------------- */ indexRelation = heap_create(indexRelationName, - indexTupDesc, false, istemp, false); + indexTupDesc, false, istemp, false); /* ---------------- * construct the index relation descriptor @@ -1075,9 +1079,9 @@ index_create(char *heapRelationName, * bootstrapping. Otherwise, we call the routine that constructs the * index. * - * In normal processing mode, the heap and index relations are closed - * by index_build() --- but we continue to hold the ShareLock on the - * heap that we acquired above, until end of transaction. + * In normal processing mode, the heap and index relations are closed by + * index_build() --- but we continue to hold the ShareLock on the heap + * that we acquired above, until end of transaction. */ if (IsBootstrapProcessingMode()) { @@ -1139,7 +1143,7 @@ index_drop(Oid indexId) * they don't exist anyway. So, no warning in that case. * ---------------- */ - if (IsTransactionBlock() && ! userIndexRelation->rd_myxactonly) + if (IsTransactionBlock() && !userIndexRelation->rd_myxactonly) elog(NOTICE, "Caution: DROP INDEX cannot be rolled back, so don't abort now"); /* ---------------- @@ -1147,7 +1151,7 @@ index_drop(Oid indexId) * ---------------- */ DeleteComments(indexId); - + /* ---------------- * fix RELATION relation * ---------------- @@ -1267,15 +1271,16 @@ FormIndexDatum(int numberOfAttributes, * -------------------------------------------- */ static -bool LockClassinfoForUpdate(Oid relid, HeapTuple rtup, Buffer *buffer, bool confirmCommitted) +bool +LockClassinfoForUpdate(Oid relid, HeapTuple rtup, Buffer *buffer, bool confirmCommitted) { HeapTuple classTuple; - Form_pg_class pgcform; + Form_pg_class pgcform; bool test; Relation relationRelation; classTuple = SearchSysCacheTuple(RELOID, PointerGetDatum(relid), - 0, 0, 0); + 0, 0, 0); if (!HeapTupleIsValid(classTuple)) return false; rtup->t_self = classTuple->t_self; @@ -1294,7 +1299,8 @@ bool LockClassinfoForUpdate(Oid relid, HeapTuple rtup, Buffer *buffer, bool conf RelationInvalidateHeapTuple(relationRelation, rtup); if (confirmCommitted) { - HeapTupleHeader th = rtup->t_data; + HeapTupleHeader th = rtup->t_data; + if (!(th->t_infomask & HEAP_XMIN_COMMITTED)) elog(ERROR, "The tuple isn't committed"); if (th->t_infomask & HEAP_XMAX_COMMITTED) @@ -1309,28 +1315,29 @@ bool LockClassinfoForUpdate(Oid relid, HeapTuple rtup, Buffer *buffer, bool conf * Indexes of the relation active ? * --------------------------------------------- */ -bool IndexesAreActive(Oid relid, bool confirmCommitted) +bool +IndexesAreActive(Oid relid, bool confirmCommitted) { - HeapTupleData tuple; + HeapTupleData tuple; Relation indexRelation; Buffer buffer; - HeapScanDesc scan; - ScanKeyData entry; + HeapScanDesc scan; + ScanKeyData entry; bool isactive; if (!LockClassinfoForUpdate(relid, &tuple, &buffer, confirmCommitted)) elog(ERROR, "IndexesAreActive couldn't lock %u", relid); if (((Form_pg_class) GETSTRUCT(&tuple))->relkind != RELKIND_RELATION) - elog(ERROR, "relation %u isn't an relation", relid); + elog(ERROR, "relation %u isn't an relation", relid); isactive = ((Form_pg_class) GETSTRUCT(&tuple))->relhasindex; ReleaseBuffer(buffer); if (isactive) return isactive; indexRelation = heap_openr(IndexRelationName, AccessShareLock); ScanKeyEntryInitialize(&entry, 0, Anum_pg_index_indrelid, - F_OIDEQ, ObjectIdGetDatum(relid)); + F_OIDEQ, ObjectIdGetDatum(relid)); scan = heap_beginscan(indexRelation, false, SnapshotNow, - 1, &entry); + 1, &entry); if (!heap_getnext(scan, 0)) isactive = true; heap_endscan(scan); @@ -1348,8 +1355,8 @@ setRelhasindexInplace(Oid relid, bool hasindex, bool immediate) Relation whichRel; Relation pg_class; HeapTuple tuple; - Form_pg_class rd_rel; - HeapScanDesc pg_class_scan = NULL; + Form_pg_class rd_rel; + HeapScanDesc pg_class_scan = NULL; /* ---------------- * This routine handles updates for only the heap relation @@ -1384,7 +1391,7 @@ setRelhasindexInplace(Oid relid, bool hasindex, bool immediate) if (!IsIgnoringSystemIndexes()) { tuple = SearchSysCacheTupleCopy(RELOID, - ObjectIdGetDatum(relid), 0, 0, 0); + ObjectIdGetDatum(relid), 0, 0, 0); } else { @@ -1406,13 +1413,15 @@ setRelhasindexInplace(Oid relid, bool hasindex, bool immediate) heap_close(pg_class, RowExclusiveLock); elog(ERROR, "setRelhasindexInplace: cannot scan RELATION relation"); } + /* - * Confirm that target tuple is locked by this transaction - * in case of immedaite updation. + * Confirm that target tuple is locked by this transaction in case of + * immedaite updation. */ if (immediate) { - HeapTupleHeader th = tuple->t_data; + HeapTupleHeader th = tuple->t_data; + if (!(th->t_infomask & HEAP_XMIN_COMMITTED)) elog(ERROR, "Immediate hasindex updation can be done only for committed tuples %x", th->t_infomask); if (th->t_infomask & HEAP_XMAX_INVALID) @@ -1447,7 +1456,7 @@ setRelhasindexInplace(Oid relid, bool hasindex, bool immediate) } else { - HeapTupleData htup; + HeapTupleData htup; Buffer buffer; htup.t_self = tuple->t_self; @@ -1485,7 +1494,7 @@ UpdateStats(Oid relid, long reltuples, bool inplace) Datum values[Natts_pg_class]; char nulls[Natts_pg_class]; char replace[Natts_pg_class]; - HeapScanDesc pg_class_scan = NULL; + HeapScanDesc pg_class_scan = NULL; bool in_place_upd; /* ---------------- @@ -1560,7 +1569,7 @@ UpdateStats(Oid relid, long reltuples, bool inplace) * pattern "CREATE TABLE; CREATE INDEX; insert data" leaves the table * with zero size statistics until a VACUUM is done. The optimizer will * generate very bad plans if the stats claim the table is empty when - * it is actually sizable. See also CREATE TABLE in heap.c. + * it is actually sizable. See also CREATE TABLE in heap.c. * ---------------- */ relpages = RelationGetNumberOfBlocks(whichRel); @@ -1697,10 +1706,12 @@ DefaultBuild(Relation heapRelation, char *nullv; long reltuples, indtuples; + #ifndef OMIT_PARTIAL_INDEX ExprContext *econtext; TupleTable tupleTable; TupleTableSlot *slot; + #endif Node *predicate; Node *oldPred; @@ -1781,6 +1792,7 @@ DefaultBuild(Relation heapRelation, reltuples++; #ifndef OMIT_PARTIAL_INDEX + /* * If oldPred != NULL, this is an EXTEND INDEX command, so skip * this tuple if it was already in the existing partial index @@ -1804,7 +1816,7 @@ DefaultBuild(Relation heapRelation, { /* SetSlotContents(slot, heapTuple); */ slot->val = heapTuple; - if (! ExecQual((List *) predicate, econtext, false)) + if (!ExecQual((List *) predicate, econtext, false)) continue; } #endif /* OMIT_PARTIAL_INDEX */ @@ -1854,18 +1866,18 @@ DefaultBuild(Relation heapRelation, /* * Since we just counted the tuples in the heap, we update its stats * in pg_class to guarantee that the planner takes advantage of the - * index we just created. But, only update statistics during - * normal index definitions, not for indices on system catalogs - * created during bootstrap processing. We must close the relations - * before updating statistics to guarantee that the relcache entries - * are flushed when we increment the command counter in UpdateStats(). - * But we do not release any locks on the relations; those will be - * held until end of transaction. + * index we just created. But, only update statistics during normal + * index definitions, not for indices on system catalogs created + * during bootstrap processing. We must close the relations before + * updating statistics to guarantee that the relcache entries are + * flushed when we increment the command counter in UpdateStats(). But + * we do not release any locks on the relations; those will be held + * until end of transaction. */ if (IsNormalProcessingMode()) { - Oid hrelid = RelationGetRelid(heapRelation); - Oid irelid = RelationGetRelid(indexRelation); + Oid hrelid = RelationGetRelid(heapRelation); + Oid irelid = RelationGetRelid(indexRelation); bool inplace = IsReindexProcessing(); heap_close(heapRelation, NoLock); @@ -1936,7 +1948,7 @@ index_build(Relation heapRelation, /* * IndexGetRelation: given an index's relation OID, get the OID of the - * relation it is an index on. Uses the system cache. + * relation it is an index on. Uses the system cache. */ static Oid IndexGetRelation(Oid indexId) @@ -2037,11 +2049,11 @@ IndexIsUniqueNoCache(Oid indexId) bool activate_index(Oid indexId, bool activate) { - if (!activate) /* Currently does nothing */ + if (!activate) /* Currently does nothing */ return true; return reindex_index(indexId, false); } - + /* -------------------------------- * reindex_index - This routine is used to recreate an index * -------------------------------- @@ -2049,18 +2061,26 @@ activate_index(Oid indexId, bool activate) bool reindex_index(Oid indexId, bool force) { - Relation iRel, indexRelation, heapRelation; - ScanKeyData entry; - HeapScanDesc scan; - HeapTuple indexTuple, procTuple, classTuple; - Form_pg_index index; - Oid heapId, procId, accessMethodId; - Node *oldPred = NULL; - PredInfo *predInfo; - AttrNumber *attributeNumberA; - FuncIndexInfo fInfo, *funcInfo = NULL; - int i, numberOfAttributes; - char *predString; + Relation iRel, + indexRelation, + heapRelation; + ScanKeyData entry; + HeapScanDesc scan; + HeapTuple indexTuple, + procTuple, + classTuple; + Form_pg_index index; + Oid heapId, + procId, + accessMethodId; + Node *oldPred = NULL; + PredInfo *predInfo; + AttrNumber *attributeNumberA; + FuncIndexInfo fInfo, + *funcInfo = NULL; + int i, + numberOfAttributes; + char *predString; bool old; old = SetReindexProcessing(true); @@ -2135,7 +2155,7 @@ reindex_index(Oid indexId, bool force) LockRelation(iRel, AccessExclusiveLock); /* - * Release any buffers associated with this index. If they're dirty, + * Release any buffers associated with this index. If they're dirty, * they're just dropped without bothering to flush to disk. */ ReleaseRelationBuffers(iRel); @@ -2149,14 +2169,13 @@ reindex_index(Oid indexId, bool force) /* Initialize the index and rebuild */ InitIndexStrategy(numberOfAttributes, iRel, accessMethodId); index_build(heapRelation, iRel, numberOfAttributes, - attributeNumberA, 0, NULL, funcInfo, predInfo); + attributeNumberA, 0, NULL, funcInfo, predInfo); /* - * index_build will close both the heap and index relations - * (but not give up the locks we hold on them). That's fine - * for the index, but we need to open the heap again. We need - * no new lock, since this backend still has the exclusive lock - * grabbed by heap_truncate. + * index_build will close both the heap and index relations (but not + * give up the locks we hold on them). That's fine for the index, but + * we need to open the heap again. We need no new lock, since this + * backend still has the exclusive lock grabbed by heap_truncate. */ iRel = index_open(indexId); Assert(iRel != NULL); @@ -2170,7 +2189,7 @@ reindex_index(Oid indexId, bool force) /* * ---------------------------- - * activate_indexes_of_a_table + * activate_indexes_of_a_table * activate/deactivate indexes of the specified table. * ---------------------------- */ @@ -2182,21 +2201,18 @@ activate_indexes_of_a_table(Oid relid, bool activate) if (!activate) setRelhasindexInplace(relid, false, true); else - { return false; - } } else { if (activate) reindex_relation(relid, false); else - { return false; - } } return true; } + /* -------------------------------- * reindex_relation - This routine is used to recreate indexes * of a relation. @@ -2206,10 +2222,11 @@ bool reindex_relation(Oid relid, bool force) { Relation indexRelation; - ScanKeyData entry; - HeapScanDesc scan; + ScanKeyData entry; + HeapScanDesc scan; HeapTuple indexTuple; - bool old, reindexed; + bool old, + reindexed; old = SetReindexProcessing(true); if (IndexesAreActive(relid, true)) @@ -2224,13 +2241,14 @@ reindex_relation(Oid relid, bool force) indexRelation = heap_openr(IndexRelationName, AccessShareLock); ScanKeyEntryInitialize(&entry, 0, Anum_pg_index_indrelid, - F_OIDEQ, ObjectIdGetDatum(relid)); + F_OIDEQ, ObjectIdGetDatum(relid)); scan = heap_beginscan(indexRelation, false, SnapshotNow, - 1, &entry); + 1, &entry); reindexed = false; while (HeapTupleIsValid(indexTuple = heap_getnext(scan, 0))) { - Form_pg_index index = (Form_pg_index) GETSTRUCT(indexTuple); + Form_pg_index index = (Form_pg_index) GETSTRUCT(indexTuple); + if (activate_index(index->indexrelid, true)) reindexed = true; else @@ -2242,9 +2260,7 @@ reindex_relation(Oid relid, bool force) heap_endscan(scan); heap_close(indexRelation, AccessShareLock); if (reindexed) - { setRelhasindexInplace(relid, true, false); - } SetReindexProcessing(old); return reindexed; } diff --git a/src/backend/catalog/indexing.c b/src/backend/catalog/indexing.c index 41337da77f8..eb3d6debcc5 100644 --- a/src/backend/catalog/indexing.c +++ b/src/backend/catalog/indexing.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.59 2000/02/18 09:28:41 inoue Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.60 2000/04/12 17:14:56 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -31,54 +31,54 @@ */ char *Name_pg_aggregate_indices[Num_pg_aggregate_indices] = - {AggregateNameTypeIndex}; +{AggregateNameTypeIndex}; char *Name_pg_am_indices[Num_pg_am_indices] = - {AmNameIndex}; +{AmNameIndex}; char *Name_pg_amop_indices[Num_pg_amop_indices] = - {AccessMethodOpidIndex, AccessMethodStrategyIndex}; +{AccessMethodOpidIndex, AccessMethodStrategyIndex}; char *Name_pg_attr_indices[Num_pg_attr_indices] = - {AttributeRelidNameIndex, AttributeRelidNumIndex}; +{AttributeRelidNameIndex, AttributeRelidNumIndex}; char *Name_pg_attrdef_indices[Num_pg_attrdef_indices] = - {AttrDefaultIndex}; +{AttrDefaultIndex}; char *Name_pg_class_indices[Num_pg_class_indices] = - {ClassNameIndex, ClassOidIndex}; +{ClassNameIndex, ClassOidIndex}; char *Name_pg_group_indices[Num_pg_group_indices] = - {GroupNameIndex, GroupSysidIndex}; +{GroupNameIndex, GroupSysidIndex}; char *Name_pg_index_indices[Num_pg_index_indices] = - {IndexRelidIndex}; +{IndexRelidIndex}; char *Name_pg_inherits_indices[Num_pg_inherits_indices] = - {InheritsRelidSeqnoIndex}; +{InheritsRelidSeqnoIndex}; char *Name_pg_language_indices[Num_pg_language_indices] = - {LanguageOidIndex, LanguageNameIndex}; +{LanguageOidIndex, LanguageNameIndex}; char *Name_pg_listener_indices[Num_pg_listener_indices] = - {ListenerRelnamePidIndex}; +{ListenerRelnamePidIndex}; char *Name_pg_opclass_indices[Num_pg_opclass_indices] = - {OpclassNameIndex, OpclassDeftypeIndex}; +{OpclassNameIndex, OpclassDeftypeIndex}; char *Name_pg_operator_indices[Num_pg_operator_indices] = - {OperatorOidIndex, OperatorNameIndex}; +{OperatorOidIndex, OperatorNameIndex}; char *Name_pg_proc_indices[Num_pg_proc_indices] = - {ProcedureOidIndex, ProcedureNameIndex}; +{ProcedureOidIndex, ProcedureNameIndex}; char *Name_pg_relcheck_indices[Num_pg_relcheck_indices] = - {RelCheckIndex}; +{RelCheckIndex}; char *Name_pg_rewrite_indices[Num_pg_rewrite_indices] = - {RewriteOidIndex, RewriteRulenameIndex}; +{RewriteOidIndex, RewriteRulenameIndex}; char *Name_pg_shadow_indices[Num_pg_shadow_indices] = - {ShadowNameIndex, ShadowSysidIndex}; +{ShadowNameIndex, ShadowSysidIndex}; char *Name_pg_statistic_indices[Num_pg_statistic_indices] = - {StatisticRelidAttnumIndex}; +{StatisticRelidAttnumIndex}; char *Name_pg_trigger_indices[Num_pg_trigger_indices] = - {TriggerRelidIndex, TriggerConstrNameIndex, TriggerConstrRelidIndex}; +{TriggerRelidIndex, TriggerConstrNameIndex, TriggerConstrRelidIndex}; char *Name_pg_type_indices[Num_pg_type_indices] = - {TypeNameIndex, TypeOidIndex}; -char *Name_pg_description_indices[Num_pg_description_indices] = - {DescriptionObjIndex}; +{TypeNameIndex, TypeOidIndex}; +char *Name_pg_description_indices[Num_pg_description_indices] = +{DescriptionObjIndex}; static HeapTuple CatalogIndexFetchTuple(Relation heapRelation, - Relation idesc, - ScanKey skey, - int16 num_keys); + Relation idesc, + ScanKey skey, + int16 num_keys); /* @@ -279,7 +279,7 @@ CatalogIndexFetchTuple(Relation heapRelation, /*--------------------------------------------------------------------- - * Class-specific index lookups + * Class-specific index lookups *--------------------------------------------------------------------- */ @@ -297,7 +297,7 @@ AggregateNameTypeIndexScan(Relation heapRelation, char *aggName, Oid aggType) Relation idesc; ScanKeyData skey[2]; HeapTuple tuple; - + ScanKeyEntryInitialize(&skey[0], (bits16) 0x0, (AttrNumber) 1, @@ -324,7 +324,7 @@ AmNameIndexScan(Relation heapRelation, char *amName) Relation idesc; ScanKeyData skey[1]; HeapTuple tuple; - + ScanKeyEntryInitialize(&skey[0], (bits16) 0x0, (AttrNumber) 1, @@ -414,8 +414,8 @@ AccessMethodStrategyIndexScan(Relation heapRelation, HeapTuple AttributeRelidNameIndexScan(Relation heapRelation, - Oid relid, - char *attname) + Oid relid, + char *attname) { Relation idesc; ScanKeyData skey[2]; @@ -444,8 +444,8 @@ AttributeRelidNameIndexScan(Relation heapRelation, HeapTuple AttributeRelidNumIndexScan(Relation heapRelation, - Oid relid, - AttrNumber attnum) + Oid relid, + AttrNumber attnum) { Relation idesc; ScanKeyData skey[2]; @@ -500,7 +500,7 @@ OpclassNameIndexScan(Relation heapRelation, char *opcName) Relation idesc; ScanKeyData skey[1]; HeapTuple tuple; - + ScanKeyEntryInitialize(&skey[0], (bits16) 0x0, (AttrNumber) 1, @@ -521,7 +521,7 @@ GroupNameIndexScan(Relation heapRelation, char *groName) Relation idesc; ScanKeyData skey[1]; HeapTuple tuple; - + ScanKeyEntryInitialize(&skey[0], (bits16) 0x0, (AttrNumber) 1, @@ -542,7 +542,7 @@ GroupSysidIndexScan(Relation heapRelation, int4 sysId) Relation idesc; ScanKeyData skey[1]; HeapTuple tuple; - + ScanKeyEntryInitialize(&skey[0], (bits16) 0x0, (AttrNumber) 1, @@ -581,8 +581,8 @@ IndexRelidIndexScan(Relation heapRelation, Oid relid) HeapTuple InheritsRelidSeqnoIndexScan(Relation heapRelation, - Oid relid, - int4 seqno) + Oid relid, + int4 seqno) { Relation idesc; ScanKeyData skey[2]; @@ -615,7 +615,7 @@ LanguageNameIndexScan(Relation heapRelation, char *lanName) Relation idesc; ScanKeyData skey[1]; HeapTuple tuple; - + ScanKeyEntryInitialize(&skey[0], (bits16) 0x0, (AttrNumber) 1, @@ -658,7 +658,7 @@ ListenerRelnamePidIndexScan(Relation heapRelation, char *relName, int4 pid) Relation idesc; ScanKeyData skey[2]; HeapTuple tuple; - + ScanKeyEntryInitialize(&skey[0], (bits16) 0x0, (AttrNumber) 1, @@ -681,10 +681,10 @@ ListenerRelnamePidIndexScan(Relation heapRelation, char *relName, int4 pid) HeapTuple OperatorNameIndexScan(Relation heapRelation, - char *oprName, - Oid oprLeft, - Oid oprRight, - char oprKind) + char *oprName, + Oid oprLeft, + Oid oprRight, + char oprKind) { Relation idesc; ScanKeyData skey[4]; @@ -810,7 +810,7 @@ ClassNameIndexScan(Relation heapRelation, char *relName) Relation idesc; ScanKeyData skey[1]; HeapTuple tuple; - + ScanKeyEntryInitialize(&skey[0], (bits16) 0x0, (AttrNumber) 1, @@ -853,7 +853,7 @@ RewriteRulenameIndexScan(Relation heapRelation, char *ruleName) Relation idesc; ScanKeyData skey[1]; HeapTuple tuple; - + ScanKeyEntryInitialize(&skey[0], (bits16) 0x0, (AttrNumber) 1, @@ -896,7 +896,7 @@ ShadowNameIndexScan(Relation heapRelation, char *useName) Relation idesc; ScanKeyData skey[1]; HeapTuple tuple; - + ScanKeyEntryInitialize(&skey[0], (bits16) 0x0, (AttrNumber) 1, @@ -917,7 +917,7 @@ ShadowSysidIndexScan(Relation heapRelation, int4 sysId) Relation idesc; ScanKeyData skey[1]; HeapTuple tuple; - + ScanKeyEntryInitialize(&skey[0], (bits16) 0x0, (AttrNumber) 1, @@ -934,8 +934,8 @@ ShadowSysidIndexScan(Relation heapRelation, int4 sysId) HeapTuple StatisticRelidAttnumIndexScan(Relation heapRelation, - Oid relId, - AttrNumber attNum) + Oid relId, + AttrNumber attNum) { Relation idesc; ScanKeyData skey[2]; @@ -1004,4 +1004,3 @@ TypeOidIndexScan(Relation heapRelation, Oid typeId) return tuple; } - diff --git a/src/backend/catalog/pg_aggregate.c b/src/backend/catalog/pg_aggregate.c index 5554752bf3f..79d796ab49d 100644 --- a/src/backend/catalog/pg_aggregate.c +++ b/src/backend/catalog/pg_aggregate.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.30 2000/03/26 19:43:58 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.31 2000/04/12 17:14:56 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -168,7 +168,7 @@ AggregateCreate(char *aggName, /* handle finalfn */ if (aggfinalfnName) { - int nargs = 0; + int nargs = 0; if (OidIsValid(xret1)) fnArgs[nargs++] = xret1; @@ -184,7 +184,7 @@ AggregateCreate(char *aggName, { if (nargs == 2) elog(ERROR, "AggregateCreate: '%s'('%s','%s') does not exist", - aggfinalfnName, aggtransfn1typeName, aggtransfn2typeName); + aggfinalfnName, aggtransfn1typeName, aggtransfn2typeName); else if (OidIsValid(xret1)) elog(ERROR, "AggregateCreate: '%s'('%s') does not exist", aggfinalfnName, aggtransfn1typeName); @@ -200,8 +200,10 @@ AggregateCreate(char *aggName, } else { - /* If no finalfn, aggregate result type is type of the sole - * state value (we already checked there is only one) + + /* + * If no finalfn, aggregate result type is type of the sole state + * value (we already checked there is only one) */ if (OidIsValid(xret1)) fret = xret1; @@ -284,9 +286,9 @@ AggNameGetInitVal(char *aggName, Oid basetype, int xfuncno, bool *isNull) Assert(xfuncno == 1 || xfuncno == 2); /* - * since we will have to use fastgetattr (in case one or both init vals - * are NULL), we will need to open the relation. Do that first to - * ensure we don't get a stale tuple from the cache. + * since we will have to use fastgetattr (in case one or both init + * vals are NULL), we will need to open the relation. Do that first + * to ensure we don't get a stale tuple from the cache. */ aggRel = heap_openr(AggregateRelationName, AccessShareLock); diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c index 6557335d994..aa23a3be8c2 100644 --- a/src/backend/catalog/pg_proc.c +++ b/src/backend/catalog/pg_proc.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.41 2000/04/04 21:44:37 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.42 2000/04/12 17:14:56 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -154,7 +154,7 @@ ProcedureCreate(char *procedureName, return tup->t_data->t_oid; #else elog(ERROR, "lookup for procedure by source needs fix (Jan)"); -#endif /* SETS_FIXED */ +#endif /* SETS_FIXED */ } } @@ -245,7 +245,7 @@ ProcedureCreate(char *procedureName, prosrc = procedureName; if (fmgr_lookupByName(prosrc) == (func_ptr) NULL) elog(ERROR, - "ProcedureCreate: there is no builtin function named \"%s\"", + "ProcedureCreate: there is no builtin function named \"%s\"", prosrc); } diff --git a/src/backend/catalog/pg_type.c b/src/backend/catalog/pg_type.c index a4e970fbfc4..4c3120c40f4 100644 --- a/src/backend/catalog/pg_type.c +++ b/src/backend/catalog/pg_type.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.49 2000/01/26 05:56:11 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.50 2000/04/12 17:14:56 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -374,7 +374,7 @@ TypeCreate(char *typeName, values[i++] = (Datum) GetUserId(); /* 2 */ values[i++] = (Datum) internalSize; /* 3 */ values[i++] = (Datum) externalSize; /* 4 */ - values[i++] = (Datum) passedByValue;/* 5 */ + values[i++] = (Datum) passedByValue; /* 5 */ values[i++] = (Datum) typeType; /* 6 */ values[i++] = (Datum) (bool) 1; /* 7 */ values[i++] = (Datum) typDelim; /* 8 */ diff --git a/src/backend/commands/_deadcode/recipe.c b/src/backend/commands/_deadcode/recipe.c index 6fd21c9e57d..a0b87743f5b 100644 --- a/src/backend/commands/_deadcode/recipe.c +++ b/src/backend/commands/_deadcode/recipe.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/_deadcode/Attic/recipe.c,v 1.10 2000/01/26 05:56:17 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/_deadcode/Attic/recipe.c,v 1.11 2000/04/12 17:15:06 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -702,7 +702,7 @@ getParamTypes(TgElement * elem, Oid *typev) if (parameterCount == FUNC_MAX_ARGS) { elog(ERROR, - "getParamTypes: Ingredients cannot take > %d arguments",FUNC_MAX_ARGS); + "getParamTypes: Ingredients cannot take > %d arguments", FUNC_MAX_ARGS); } t = elem->inTypes->val[j]; if (strcmp(t, "opaque") == 0) @@ -810,7 +810,7 @@ tg_parseSubQuery(TgRecipe * r, TgNode * n, TeeInfo * teeInfo) { TgElement *elem; char *funcName; - Oid typev[FUNC_MAX_ARGS], /* eight arguments maximum */ + Oid typev[FUNC_MAX_ARGS], /* eight arguments maximum */ relid; int i, parameterCount; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index e7cf7ac6748..f6079885fa7 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.58 2000/01/26 05:56:12 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.59 2000/04/12 17:14:57 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -155,12 +155,13 @@ Async_Notify(char *relname) /* no point in making duplicate entries in the list ... */ if (!AsyncExistsPendingNotify(relname)) { + /* * We allocate list memory from the global malloc pool to ensure - * that it will live until we want to use it. This is probably not - * necessary any longer, since we will use it before the end of the - * transaction. DLList only knows how to use malloc() anyway, but we - * could probably palloc() the strings... + * that it will live until we want to use it. This is probably + * not necessary any longer, since we will use it before the end + * of the transaction. DLList only knows how to use malloc() + * anyway, but we could probably palloc() the strings... */ notifyName = strdup(relname); DLAddHead(pendingNotifies, DLNewElem(notifyName)); @@ -466,6 +467,7 @@ AtCommit_Notify() if (listenerPID == MyProcPid) { + /* * Self-notify: no need to bother with table update. * Indeed, we *must not* clear the notification field in @@ -491,6 +493,7 @@ AtCommit_Notify() */ if (kill(listenerPID, SIGUSR2) < 0) { + /* * Get rid of pg_listener entry if it refers to a PID * that no longer exists. Presumably, that backend @@ -514,7 +517,7 @@ AtCommit_Notify() if (RelationGetForm(lRel)->relhasindex) { Relation idescs[Num_pg_listener_indices]; - + CatalogOpenIndices(Num_pg_listener_indices, Name_pg_listener_indices, idescs); CatalogIndexInsert(idescs, Num_pg_listener_indices, lRel, rTuple); CatalogCloseIndices(Num_pg_listener_indices, idescs); @@ -780,7 +783,7 @@ ProcessIncomingNotify(void) if (RelationGetForm(lRel)->relhasindex) { Relation idescs[Num_pg_listener_indices]; - + CatalogOpenIndices(Num_pg_listener_indices, Name_pg_listener_indices, idescs); CatalogIndexInsert(idescs, Num_pg_listener_indices, lRel, rTuple); CatalogCloseIndices(Num_pg_listener_indices, idescs); diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c index 299101337f1..0cbf4a2177b 100644 --- a/src/backend/commands/cluster.c +++ b/src/backend/commands/cluster.c @@ -15,7 +15,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.50 2000/01/26 05:56:13 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.51 2000/04/12 17:14:57 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -104,8 +104,8 @@ cluster(char *oldrelname, char *oldindexname) * Like vacuum, cluster spans transactions, so I'm going to handle it * in the same way: commit and restart transactions where needed. * - * We grab exclusive access to the target rel and index for the - * duration of the initial transaction. + * We grab exclusive access to the target rel and index for the duration + * of the initial transaction. */ OldHeap = heap_openr(oldrelname, AccessExclusiveLock); @@ -115,7 +115,7 @@ cluster(char *oldrelname, char *oldindexname) LockRelation(OldIndex, AccessExclusiveLock); OIDOldIndex = RelationGetRelid(OldIndex); - heap_close(OldHeap, NoLock); /* do NOT give up the locks */ + heap_close(OldHeap, NoLock);/* do NOT give up the locks */ index_close(OldIndex); /* diff --git a/src/backend/commands/command.c b/src/backend/commands/command.c index b75f3840a87..2b9f6a257b1 100644 --- a/src/backend/commands/command.c +++ b/src/backend/commands/command.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.70 2000/03/09 05:00:23 inoue Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.71 2000/04/12 17:14:57 momjian Exp $ * * NOTES * The PortalExecutorHeapMemory crap needs to be eliminated @@ -51,7 +51,7 @@ #include "access/genam.h" #include "optimizer/clauses.h" #include "../parser/parse.h" -#endif /* _DROP_COLUMN_HACK__ */ +#endif /* _DROP_COLUMN_HACK__ */ /* ---------------- * PortalExecutorHeapMemory stuff @@ -262,7 +262,7 @@ PerformPortalClose(char *name, CommandDest dest) } /* ---------------- - * AlterTableAddColumn + * AlterTableAddColumn * (formerly known as PerformAddAttribute) * * adds an additional attribute to a relation @@ -327,8 +327,8 @@ AlterTableAddColumn(const char *relationName, #endif /* - * Grab an exclusive lock on the target table, which we will NOT release - * until end of transaction. + * Grab an exclusive lock on the target table, which we will NOT + * release until end of transaction. */ rel = heap_openr(relationName, AccessExclusiveLock); myrelid = RelationGetRelid(rel); @@ -341,7 +341,7 @@ AlterTableAddColumn(const char *relationName, elog(ERROR, "Can't add a NOT NULL attribute to an existing relation"); if (colDef->raw_default || colDef->cooked_default) - elog(ERROR, "Adding columns with defaults is not implemented."); + elog(ERROR, "Adding columns with defaults is not implemented."); /* @@ -370,7 +370,7 @@ AlterTableAddColumn(const char *relationName, */ foreach(child, children) { - Oid childrelid = lfirsti(child); + Oid childrelid = lfirsti(child); if (childrelid == myrelid) continue; @@ -514,13 +514,13 @@ static void drop_default(Oid relid, int16 attnum); */ void AlterTableAlterColumn(const char *relationName, - bool inh, const char *colName, - Node *newDefault) + bool inh, const char *colName, + Node *newDefault) { - Relation rel; - HeapTuple tuple; - int16 attnum; - Oid myrelid; + Relation rel; + HeapTuple tuple; + int16 attnum; + Oid myrelid; if (!allowSystemTableMods && IsSystemRelationName(relationName)) elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog", @@ -530,121 +530,122 @@ AlterTableAlterColumn(const char *relationName, elog(ERROR, "ALTER TABLE: permission denied"); #endif - rel = heap_openr(relationName, AccessExclusiveLock); - myrelid = RelationGetRelid(rel); - heap_close(rel, NoLock); + rel = heap_openr(relationName, AccessExclusiveLock); + myrelid = RelationGetRelid(rel); + heap_close(rel, NoLock); - /* - * Propagate to children if desired - */ + /* + * Propagate to children if desired + */ if (inh) - { - List *child, - *children; - - /* this routine is actually in the planner */ - children = find_all_inheritors(myrelid); - - /* - * find_all_inheritors does the recursive search of the - * inheritance hierarchy, so all we have to do is process all - * of the relids in the list that it returns. - */ - foreach(child, children) + { + List *child, + *children; + + /* this routine is actually in the planner */ + children = find_all_inheritors(myrelid); + + /* + * find_all_inheritors does the recursive search of the + * inheritance hierarchy, so all we have to do is process all of + * the relids in the list that it returns. + */ + foreach(child, children) { - Oid childrelid = lfirsti(child); - - if (childrelid == myrelid) - continue; - rel = heap_open(childrelid, AccessExclusiveLock); - AlterTableAlterColumn(RelationGetRelationName(rel), - false, colName, newDefault); - heap_close(rel, AccessExclusiveLock); - } - } - - /* -= now do the thing on this relation =- */ - - /* reopen the business */ - rel = heap_openr((char *)relationName, AccessExclusiveLock); - - /* - * get the number of the attribute - */ - tuple = SearchSysCacheTuple(ATTNAME, - ObjectIdGetDatum(myrelid), - NameGetDatum(namein((char *)colName)), - 0, 0); - - if (!HeapTupleIsValid(tuple)) - { - heap_close(rel, AccessExclusiveLock); - elog(ERROR, "ALTER TABLE: relation \"%s\" has no column \"%s\"", - relationName, colName); - } - - attnum = ((Form_pg_attribute) GETSTRUCT(tuple))->attnum; - - if (newDefault) /* SET DEFAULT */ - { - List* rawDefaults = NIL; - RawColumnDefault *rawEnt; - - /* Get rid of the old one first */ - drop_default(myrelid, attnum); + Oid childrelid = lfirsti(child); + + if (childrelid == myrelid) + continue; + rel = heap_open(childrelid, AccessExclusiveLock); + AlterTableAlterColumn(RelationGetRelationName(rel), + false, colName, newDefault); + heap_close(rel, AccessExclusiveLock); + } + } + + /* -= now do the thing on this relation =- */ + + /* reopen the business */ + rel = heap_openr((char *) relationName, AccessExclusiveLock); + + /* + * get the number of the attribute + */ + tuple = SearchSysCacheTuple(ATTNAME, + ObjectIdGetDatum(myrelid), + NameGetDatum(namein((char *) colName)), + 0, 0); + + if (!HeapTupleIsValid(tuple)) + { + heap_close(rel, AccessExclusiveLock); + elog(ERROR, "ALTER TABLE: relation \"%s\" has no column \"%s\"", + relationName, colName); + } + + attnum = ((Form_pg_attribute) GETSTRUCT(tuple))->attnum; + + if (newDefault) /* SET DEFAULT */ + { + List *rawDefaults = NIL; + RawColumnDefault *rawEnt; + + /* Get rid of the old one first */ + drop_default(myrelid, attnum); rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault)); rawEnt->attnum = attnum; - rawEnt->raw_default = newDefault; + rawEnt->raw_default = newDefault; rawDefaults = lappend(rawDefaults, rawEnt); - /* - * This function is intended for CREATE TABLE, - * so it processes a _list_ of defaults, but we just do one. - */ - AddRelationRawConstraints(rel, rawDefaults, NIL); - } - - else /* DROP DEFAULT */ - { - Relation attr_rel; - ScanKeyData scankeys[3]; - HeapScanDesc scan; - HeapTuple tuple; - - attr_rel = heap_openr(AttributeRelationName, AccessExclusiveLock); - ScanKeyEntryInitialize(&scankeys[0], 0x0, Anum_pg_attribute_attrelid, F_OIDEQ, - ObjectIdGetDatum(myrelid)); - ScanKeyEntryInitialize(&scankeys[1], 0x0, Anum_pg_attribute_attnum, F_INT2EQ, - Int16GetDatum(attnum)); - ScanKeyEntryInitialize(&scankeys[2], 0x0, Anum_pg_attribute_atthasdef, F_BOOLEQ, - TRUE); - - scan = heap_beginscan(attr_rel, false, SnapshotNow, 3, scankeys); - AssertState(scan!=NULL); - - if (HeapTupleIsValid(tuple = heap_getnext(scan, 0))) - { - HeapTuple newtuple; - Relation irelations[Num_pg_attr_indices]; - - /* update to false */ - newtuple = heap_copytuple(tuple); - ((Form_pg_attribute) GETSTRUCT(newtuple))->atthasdef = FALSE; - heap_update(attr_rel, &tuple->t_self, newtuple, NULL); - - /* keep the system catalog indices current */ - CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, irelations); - CatalogIndexInsert(irelations, Num_pg_attr_indices, attr_rel, newtuple); - CatalogCloseIndices(Num_pg_attr_indices, irelations); - - /* get rid of actual default definition */ - drop_default(myrelid, attnum); - } - - heap_endscan(scan); - heap_close(attr_rel, NoLock); - } + /* + * This function is intended for CREATE TABLE, so it processes a + * _list_ of defaults, but we just do one. + */ + AddRelationRawConstraints(rel, rawDefaults, NIL); + } + + else +/* DROP DEFAULT */ + { + Relation attr_rel; + ScanKeyData scankeys[3]; + HeapScanDesc scan; + HeapTuple tuple; + + attr_rel = heap_openr(AttributeRelationName, AccessExclusiveLock); + ScanKeyEntryInitialize(&scankeys[0], 0x0, Anum_pg_attribute_attrelid, F_OIDEQ, + ObjectIdGetDatum(myrelid)); + ScanKeyEntryInitialize(&scankeys[1], 0x0, Anum_pg_attribute_attnum, F_INT2EQ, + Int16GetDatum(attnum)); + ScanKeyEntryInitialize(&scankeys[2], 0x0, Anum_pg_attribute_atthasdef, F_BOOLEQ, + TRUE); + + scan = heap_beginscan(attr_rel, false, SnapshotNow, 3, scankeys); + AssertState(scan != NULL); + + if (HeapTupleIsValid(tuple = heap_getnext(scan, 0))) + { + HeapTuple newtuple; + Relation irelations[Num_pg_attr_indices]; + + /* update to false */ + newtuple = heap_copytuple(tuple); + ((Form_pg_attribute) GETSTRUCT(newtuple))->atthasdef = FALSE; + heap_update(attr_rel, &tuple->t_self, newtuple, NULL); + + /* keep the system catalog indices current */ + CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, irelations); + CatalogIndexInsert(irelations, Num_pg_attr_indices, attr_rel, newtuple); + CatalogCloseIndices(Num_pg_attr_indices, irelations); + + /* get rid of actual default definition */ + drop_default(myrelid, attnum); + } + + heap_endscan(scan); + heap_close(attr_rel, NoLock); + } heap_close(rel, NoLock); } @@ -654,33 +655,33 @@ AlterTableAlterColumn(const char *relationName, static void drop_default(Oid relid, int16 attnum) { - ScanKeyData scankeys[2]; - HeapScanDesc scan; - Relation attrdef_rel; - HeapTuple tuple; + ScanKeyData scankeys[2]; + HeapScanDesc scan; + Relation attrdef_rel; + HeapTuple tuple; - attrdef_rel = heap_openr(AttrDefaultRelationName, AccessExclusiveLock); - ScanKeyEntryInitialize(&scankeys[0], 0x0, Anum_pg_attrdef_adrelid, F_OIDEQ, - ObjectIdGetDatum(relid)); - ScanKeyEntryInitialize(&scankeys[1], 0x0, Anum_pg_attrdef_adnum, F_INT2EQ, - Int16GetDatum(attnum)); + attrdef_rel = heap_openr(AttrDefaultRelationName, AccessExclusiveLock); + ScanKeyEntryInitialize(&scankeys[0], 0x0, Anum_pg_attrdef_adrelid, F_OIDEQ, + ObjectIdGetDatum(relid)); + ScanKeyEntryInitialize(&scankeys[1], 0x0, Anum_pg_attrdef_adnum, F_INT2EQ, + Int16GetDatum(attnum)); - scan = heap_beginscan(attrdef_rel, false, SnapshotNow, 2, scankeys); - AssertState(scan!=NULL); + scan = heap_beginscan(attrdef_rel, false, SnapshotNow, 2, scankeys); + AssertState(scan != NULL); - if (HeapTupleIsValid(tuple = heap_getnext(scan, 0))) - heap_delete(attrdef_rel, &tuple->t_self, NULL); + if (HeapTupleIsValid(tuple = heap_getnext(scan, 0))) + heap_delete(attrdef_rel, &tuple->t_self, NULL); - heap_endscan(scan); + heap_endscan(scan); - heap_close(attrdef_rel, NoLock); + heap_close(attrdef_rel, NoLock); } #ifdef _DROP_COLUMN_HACK__ /* * ALTER TABLE DROP COLUMN trial implementation - * + * */ /* @@ -690,17 +691,17 @@ typedef struct SysScanDescData { Relation heap_rel; Relation irel; - HeapScanDesc scan; - IndexScanDesc iscan; - HeapTupleData tuple; + HeapScanDesc scan; + IndexScanDesc iscan; + HeapTupleData tuple; Buffer buffer; -} SysScanDescData, *SysScanDesc; - +} SysScanDescData, *SysScanDesc; + static void * systable_beginscan(Relation rel, const char *indexRelname, int nkeys, ScanKey entry) { - bool hasindex = (rel->rd_rel->relhasindex && !IsIgnoringSystemIndexes()); - SysScanDesc sysscan; + bool hasindex = (rel->rd_rel->relhasindex && !IsIgnoringSystemIndexes()); + SysScanDesc sysscan; sysscan = (SysScanDesc) palloc(sizeof(SysScanDescData)); sysscan->heap_rel = rel; @@ -710,7 +711,7 @@ systable_beginscan(Relation rel, const char *indexRelname, int nkeys, ScanKey en sysscan->buffer = InvalidBuffer; if (hasindex) { - sysscan->irel = index_openr((char *)indexRelname); + sysscan->irel = index_openr((char *) indexRelname); sysscan->iscan = index_beginscan(sysscan->irel, false, nkeys, entry); } else @@ -720,7 +721,7 @@ systable_beginscan(Relation rel, const char *indexRelname, int nkeys, ScanKey en static void systable_endscan(void *scan) { - SysScanDesc sysscan = (SysScanDesc) scan; + SysScanDesc sysscan = (SysScanDesc) scan; if (sysscan->irel) { @@ -736,9 +737,9 @@ systable_endscan(void *scan) static HeapTuple systable_getnext(void *scan) { - SysScanDesc sysscan = (SysScanDesc) scan; + SysScanDesc sysscan = (SysScanDesc) scan; HeapTuple htup = (HeapTuple) NULL; - RetrieveIndexResult indexRes; + RetrieveIndexResult indexRes; if (sysscan->irel) { @@ -774,50 +775,55 @@ find_attribute_walker(Node *node, int attnum) return false; if (IsA(node, Var)) { - Var *var = (Var *) node; + Var *var = (Var *) node; + if (var->varlevelsup == 0 && var->varno == 1 && var->varattno == attnum) return true; } - return expression_tree_walker(node, find_attribute_walker, (void *)attnum); + return expression_tree_walker(node, find_attribute_walker, (void *) attnum); } static bool find_attribute_in_node(Node *node, int attnum) { - return expression_tree_walker(node, find_attribute_walker, (void *)attnum); + return expression_tree_walker(node, find_attribute_walker, (void *) attnum); } + /* * Remove/check references for the column */ static bool RemoveColumnReferences(Oid reloid, int attnum, bool checkonly, HeapTuple reltup) { - Relation indexRelation, rcrel; - ScanKeyData entry; - HeapScanDesc scan; - void *sysscan; - HeapTuple htup, indexTuple; - Form_pg_index index; - Form_pg_relcheck relcheck; - Form_pg_class pgcform = (Form_pg_class) NULL; - int i; + Relation indexRelation, + rcrel; + ScanKeyData entry; + HeapScanDesc scan; + void *sysscan; + HeapTuple htup, + indexTuple; + Form_pg_index index; + Form_pg_relcheck relcheck; + Form_pg_class pgcform = (Form_pg_class) NULL; + int i; bool checkok = true; - + if (!checkonly) - pgcform = (Form_pg_class) GETSTRUCT (reltup); + pgcform = (Form_pg_class) GETSTRUCT(reltup); + /* - * Remove/check constraints here + * Remove/check constraints here */ ScanKeyEntryInitialize(&entry, (bits16) 0x0, Anum_pg_relcheck_rcrelid, - (RegProcedure) F_OIDEQ, ObjectIdGetDatum(reloid)); + (RegProcedure) F_OIDEQ, ObjectIdGetDatum(reloid)); rcrel = heap_openr(RelCheckRelationName, RowExclusiveLock); - sysscan = systable_beginscan(rcrel, RelCheckIndex,1 ,&entry); + sysscan = systable_beginscan(rcrel, RelCheckIndex, 1, &entry); while (HeapTupleIsValid(htup = systable_getnext(sysscan))) { - char *ccbin; - Node *node; + char *ccbin; + Node *node; relcheck = (Form_pg_relcheck) GETSTRUCT(htup); ccbin = textout(&relcheck->rcbin); @@ -843,15 +849,15 @@ RemoveColumnReferences(Oid reloid, int attnum, bool checkonly, HeapTuple reltup) heap_close(rcrel, NoLock); /* - * What to do with triggers/rules/views/procedues ? + * What to do with triggers/rules/views/procedues ? */ /* - * Remove/check indexes + * Remove/check indexes */ indexRelation = heap_openr(IndexRelationName, RowExclusiveLock); ScanKeyEntryInitialize(&entry, 0, Anum_pg_index_indrelid, F_OIDEQ, - ObjectIdGetDatum(reloid)); + ObjectIdGetDatum(reloid)); scan = heap_beginscan(indexRelation, false, SnapshotNow, 1, &entry); while (HeapTupleIsValid(indexTuple = heap_getnext(scan, 0))) { @@ -870,8 +876,8 @@ RemoveColumnReferences(Oid reloid, int attnum, bool checkonly, HeapTuple reltup) else { htup = SearchSysCacheTuple(RELOID, - ObjectIdGetDatum(index->indexrelid), - 0, 0, 0); + ObjectIdGetDatum(index->indexrelid), + 0, 0, 0); RemoveIndex(NameStr(((Form_pg_class) GETSTRUCT(htup))->relname)); } break; @@ -883,33 +889,38 @@ RemoveColumnReferences(Oid reloid, int attnum, bool checkonly, HeapTuple reltup) return checkok; } -#endif /* _DROP_COLUMN_HACK__ */ + +#endif /* _DROP_COLUMN_HACK__ */ /* * ALTER TABLE DROP COLUMN */ void AlterTableDropColumn(const char *relationName, - bool inh, const char *colName, - int behavior) + bool inh, const char *colName, + int behavior) { #ifdef _DROP_COLUMN_HACK__ - Relation rel, attrdesc, adrel; - Oid myrelid, attoid; + Relation rel, + attrdesc, + adrel; + Oid myrelid, + attoid; HeapTuple reltup; - HeapTupleData classtuple; + HeapTupleData classtuple; Buffer buffer; Form_pg_attribute attribute; HeapTuple tup; Relation idescs[Num_pg_attr_indices]; - int attnum; + int attnum; bool hasindex; char dropColname[32]; - void *sysscan; - ScanKeyData scankeys[2]; + void *sysscan; + ScanKeyData scankeys[2]; - if (inh) + if (inh) elog(ERROR, "ALTER TABLE / DROP COLUMN with inherit option is not supported yet"); + /* * permissions checking. this would normally be done in utility.c, * but this particular routine is recursive. @@ -925,25 +936,25 @@ AlterTableDropColumn(const char *relationName, #endif /* - * Grab an exclusive lock on the target table, which we will NOT release - * until end of transaction. + * Grab an exclusive lock on the target table, which we will NOT + * release until end of transaction. */ rel = heap_openr(relationName, AccessExclusiveLock); myrelid = RelationGetRelid(rel); heap_close(rel, NoLock); /* close rel but keep lock! */ /* - * What to do when rel has inheritors ? + * What to do when rel has inheritors ? */ if (length(find_all_inheritors(myrelid)) > 1) elog(ERROR, "ALTER TABLE: cannot drop a column on table that is inherited from"); /* - * lock the pg_class tuple for update + * lock the pg_class tuple for update */ reltup = SearchSysCacheTuple(RELNAME, PointerGetDatum(relationName), - 0, 0, 0); + 0, 0, 0); if (!HeapTupleIsValid(reltup)) elog(ERROR, "ALTER TABLE: relation \"%s\" not found", @@ -976,19 +987,20 @@ AlterTableDropColumn(const char *relationName, * Get the target pg_attribute tuple */ tup = SearchSysCacheTupleCopy(ATTNAME, - ObjectIdGetDatum(reltup->t_data->t_oid), - PointerGetDatum(colName), 0, 0); + ObjectIdGetDatum(reltup->t_data->t_oid), + PointerGetDatum(colName), 0, 0); if (!HeapTupleIsValid(tup)) elog(ERROR, "ALTER TABLE: column name \"%s\" doesn't exist in table \"%s\"", - colName, relationName); + colName, relationName); attribute = (Form_pg_attribute) GETSTRUCT(tup); if (attribute->attnum <= 0) elog(ERROR, "ALTER TABLE: column name \"%s\" was already dropped", colName); attnum = attribute->attnum; attoid = tup->t_data->t_oid; + /* - * Check constraints/indices etc here + * Check constraints/indices etc here */ if (behavior != CASCADE) { @@ -997,7 +1009,7 @@ AlterTableDropColumn(const char *relationName, } /* - * change the target pg_attribute tuple + * change the target pg_attribute tuple */ sprintf(dropColname, "*already Dropped*%d", attnum); namestrcpy(&(attribute->attname), dropColname); @@ -1009,7 +1021,7 @@ AlterTableDropColumn(const char *relationName, { CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, idescs); CatalogIndexInsert(idescs, Num_pg_attr_indices, - attrdesc, tup); + attrdesc, tup); CatalogCloseIndices(Num_pg_attr_indices, idescs); } heap_close(attrdesc, NoLock); @@ -1020,15 +1032,17 @@ AlterTableDropColumn(const char *relationName, /* delete attrdef */ adrel = heap_openr(AttrDefaultRelationName, RowExclusiveLock); ScanKeyEntryInitialize(&scankeys[0], 0x0, Anum_pg_attrdef_adrelid, - F_OIDEQ, ObjectIdGetDatum(myrelid)); - /* Oops pg_attrdef doesn't have (adrelid,adnum) index - ScanKeyEntryInitialize(&scankeys[1], 0x0, Anum_pg_attrdef_adnum, - F_INT2EQ, Int16GetDatum(attnum)); - sysscan = systable_beginscan(adrel, AttrDefaultIndex, 2, scankeys); - */ + F_OIDEQ, ObjectIdGetDatum(myrelid)); + + /* + * Oops pg_attrdef doesn't have (adrelid,adnum) index + * ScanKeyEntryInitialize(&scankeys[1], 0x0, Anum_pg_attrdef_adnum, + * F_INT2EQ, Int16GetDatum(attnum)); sysscan = + * systable_beginscan(adrel, AttrDefaultIndex, 2, scankeys); + */ sysscan = systable_beginscan(adrel, AttrDefaultIndex, 1, scankeys); while (HeapTupleIsValid(tup = systable_getnext(sysscan))) - { + { if (((Form_pg_attrdef) GETSTRUCT(tup))->adnum == attnum) { heap_delete(adrel, &tup->t_self, NULL); @@ -1037,8 +1051,9 @@ AlterTableDropColumn(const char *relationName, } systable_endscan(sysscan); heap_close(adrel, NoLock); + /* - * Remove objects which reference this column + * Remove objects which reference this column */ if (behavior == CASCADE) { @@ -1055,8 +1070,8 @@ AlterTableDropColumn(const char *relationName, heap_freetuple(reltup); heap_close(rel, NoLock); #else - elog(ERROR, "ALTER TABLE / DROP COLUMN is not implemented"); -#endif /* _DROP_COLUMN_HACK__ */ + elog(ERROR, "ALTER TABLE / DROP COLUMN is not implemented"); +#endif /* _DROP_COLUMN_HACK__ */ } @@ -1066,76 +1081,80 @@ AlterTableDropColumn(const char *relationName, */ void AlterTableAddConstraint(const char *relationName, - bool inh, Node *newConstraint) + bool inh, Node *newConstraint) { - if (newConstraint == NULL) + if (newConstraint == NULL) elog(ERROR, "ALTER TABLE / ADD CONSTRAINT passed invalid constraint."); - switch (nodeTag(newConstraint)) + switch (nodeTag(newConstraint)) { case T_Constraint: elog(ERROR, "ALTER TABLE / ADD CONSTRAINT is not implemented"); case T_FkConstraint: { - FkConstraint *fkconstraint=(FkConstraint *)newConstraint; - Relation rel; + FkConstraint *fkconstraint = (FkConstraint *) newConstraint; + Relation rel; HeapScanDesc scan; - HeapTuple tuple; - Trigger trig; - List *list; - int count; + HeapTuple tuple; + Trigger trig; + List *list; + int count; - /* + /* * Grab an exclusive lock on the pk table, so that someone - * doesn't delete rows out from under us. + * doesn't delete rows out from under us. */ rel = heap_openr(fkconstraint->pktable_name, AccessExclusiveLock); heap_close(rel, NoLock); - /* - * Grab an exclusive lock on the fk table, and then scan through - * each tuple, calling the RI_FKey_Match_Ins (insert trigger) - * as if that tuple had just been inserted. If any of those - * fail, it should elog(ERROR) and that's that. + /* + * Grab an exclusive lock on the fk table, and then scan + * through each tuple, calling the RI_FKey_Match_Ins + * (insert trigger) as if that tuple had just been + * inserted. If any of those fail, it should elog(ERROR) + * and that's that. */ rel = heap_openr(relationName, AccessExclusiveLock); trig.tgoid = 0; trig.tgname = "<unknown>"; - trig.tgfoid = 0; + trig.tgfoid = 0; trig.tgtype = 0; trig.tgenabled = TRUE; trig.tgisconstraint = TRUE; trig.tginitdeferred = FALSE; trig.tgdeferrable = FALSE; - trig.tgargs = (char **)palloc( - sizeof(char *) * (4 + length(fkconstraint->fk_attrs) - + length(fkconstraint->pk_attrs))); - + trig.tgargs = (char **) palloc( + sizeof(char *) * (4 + length(fkconstraint->fk_attrs) + + length(fkconstraint->pk_attrs))); + trig.tgargs[0] = "<unnamed>"; - trig.tgargs[1] = (char *)relationName; + trig.tgargs[1] = (char *) relationName; trig.tgargs[2] = fkconstraint->pktable_name; trig.tgargs[3] = fkconstraint->match_type; count = 4; - foreach (list, fkconstraint->fk_attrs) + foreach(list, fkconstraint->fk_attrs) { - Ident *fk_at = lfirst(list); + Ident *fk_at = lfirst(list); + trig.tgargs[count++] = fk_at->name; } - foreach (list, fkconstraint->pk_attrs) + foreach(list, fkconstraint->pk_attrs) { - Ident *pk_at = lfirst(list); + Ident *pk_at = lfirst(list); + trig.tgargs[count++] = pk_at->name; } trig.tgnargs = count; scan = heap_beginscan(rel, false, SnapshotNow, 0, NULL); - AssertState(scan!=NULL); + AssertState(scan != NULL); while (HeapTupleIsValid(tuple = heap_getnext(scan, 0))) { TriggerData newtrigdata; + newtrigdata.tg_event = TRIGGER_EVENT_INSERT | TRIGGER_EVENT_ROW; newtrigdata.tg_relation = rel; newtrigdata.tg_trigtuple = tuple; @@ -1149,7 +1168,8 @@ AlterTableAddConstraint(const char *relationName, /* Make a call to the check function */ } heap_endscan(scan); - heap_close(rel, NoLock); /* close rel but keep lock! */ + heap_close(rel, NoLock); /* close rel but keep + * lock! */ pfree(trig.tgargs); } @@ -1166,10 +1186,10 @@ AlterTableAddConstraint(const char *relationName, */ void AlterTableDropConstraint(const char *relationName, - bool inh, const char *constrName, - int behavior) + bool inh, const char *constrName, + int behavior) { - elog(ERROR, "ALTER TABLE / DROP CONSTRAINT is not implemented"); + elog(ERROR, "ALTER TABLE / DROP CONSTRAINT is not implemented"); } @@ -1186,7 +1206,7 @@ LockTableCommand(LockStmt *lockstmt) int aclresult; rel = heap_openr(lockstmt->relname, NoLock); - if (! RelationIsValid(rel)) + if (!RelationIsValid(rel)) elog(ERROR, "Relation '%s' does not exist", lockstmt->relname); if (lockstmt->mode == AccessShareLock) diff --git a/src/backend/commands/comment.c b/src/backend/commands/comment.c index 649025b4a13..3fe7b6f6347 100644 --- a/src/backend/commands/comment.c +++ b/src/backend/commands/comment.c @@ -67,44 +67,47 @@ static void CommentTrigger(char *trigger, char *relation, char *comments); *------------------------------------------------------------------ */ -void CommentObject(int objtype, char *objname, char *objproperty, - List *objlist, char *comment) { - - switch (objtype) { - case (INDEX): - case (SEQUENCE): - case (TABLE): - case (VIEW): - CommentRelation(objtype, objname, comment); - break; - case (COLUMN): - CommentAttribute(objname, objproperty, comment); - break; - case (DATABASE): - CommentDatabase(objname, comment); - break; - case (RULE): - CommentRewrite(objname, comment); - break; - case (TYPE_P): - CommentType(objname, comment); - break; - case (AGGREGATE): - CommentAggregate(objname, objproperty, comment); - break; - case (FUNCTION): - CommentProc(objname, objlist, comment); - break; - case (OPERATOR): - CommentOperator(objname, objlist, comment); - break; - case (TRIGGER): - CommentTrigger(objname, objproperty, comment); - break; - default: - elog(ERROR, "An attempt was made to comment on a unknown type: %i", - objtype); - } +void +CommentObject(int objtype, char *objname, char *objproperty, + List *objlist, char *comment) +{ + + switch (objtype) + { + case (INDEX): + case (SEQUENCE): + case (TABLE): + case (VIEW): + CommentRelation(objtype, objname, comment); + break; + case (COLUMN): + CommentAttribute(objname, objproperty, comment); + break; + case (DATABASE): + CommentDatabase(objname, comment); + break; + case (RULE): + CommentRewrite(objname, comment); + break; + case (TYPE_P): + CommentType(objname, comment); + break; + case (AGGREGATE): + CommentAggregate(objname, objproperty, comment); + break; + case (FUNCTION): + CommentProc(objname, objlist, comment); + break; + case (OPERATOR): + CommentOperator(objname, objlist, comment); + break; + case (TRIGGER): + CommentTrigger(objname, objproperty, comment); + break; + default: + elog(ERROR, "An attempt was made to comment on a unknown type: %i", + objtype); + } } @@ -120,87 +123,99 @@ void CommentObject(int objtype, char *objname, char *objproperty, *------------------------------------------------------------------ */ -void CreateComments(Oid oid, char *comment) { - - Relation description; - TupleDesc tupDesc; - HeapScanDesc scan; - ScanKeyData entry; - HeapTuple desctuple = NULL, searchtuple; - Datum values[Natts_pg_description]; - char nulls[Natts_pg_description]; - char replaces[Natts_pg_description]; - bool modified = false; - int i; - - /*** Open pg_description, form a new tuple, if necessary ***/ - - description = heap_openr(DescriptionRelationName, RowExclusiveLock); - tupDesc = description->rd_att; - if ((comment != NULL) && (strlen(comment) > 0)) { - for (i = 0; i < Natts_pg_description; i++) { - nulls[i] = ' '; - replaces[i] = 'r'; - values[i] = (Datum) NULL; - } - i = 0; - values[i++] = ObjectIdGetDatum(oid); - values[i++] = (Datum) fmgr(F_TEXTIN, comment); - } - - /*** Now, open pg_description and attempt to find the old tuple ***/ - - ScanKeyEntryInitialize(&entry, 0x0, Anum_pg_description_objoid, F_OIDEQ, - ObjectIdGetDatum(oid)); - scan = heap_beginscan(description, false, SnapshotNow, 1, &entry); - searchtuple = heap_getnext(scan, 0); - - /*** If a previous tuple exists, either delete or prep replacement ***/ - - if (HeapTupleIsValid(searchtuple)) { - - /*** If the comment is blank, call heap_delete, else heap_update ***/ - - if ((comment == NULL) || (strlen(comment) == 0)) { - heap_delete(description, &searchtuple->t_self, NULL); - } else { - desctuple = heap_modifytuple(searchtuple, description, values, - nulls, replaces); - heap_update(description, &searchtuple->t_self, desctuple, NULL); - modified = TRUE; - } - - } else { - - /*** Only if comment is non-blank do we form a new tuple ***/ - - if ((comment != NULL) && (strlen(comment) > 0)) { - desctuple = heap_formtuple(tupDesc, values, nulls); - heap_insert(description, desctuple); - modified = TRUE; +void +CreateComments(Oid oid, char *comment) +{ + + Relation description; + TupleDesc tupDesc; + HeapScanDesc scan; + ScanKeyData entry; + HeapTuple desctuple = NULL, + searchtuple; + Datum values[Natts_pg_description]; + char nulls[Natts_pg_description]; + char replaces[Natts_pg_description]; + bool modified = false; + int i; + + /*** Open pg_description, form a new tuple, if necessary ***/ + + description = heap_openr(DescriptionRelationName, RowExclusiveLock); + tupDesc = description->rd_att; + if ((comment != NULL) && (strlen(comment) > 0)) + { + for (i = 0; i < Natts_pg_description; i++) + { + nulls[i] = ' '; + replaces[i] = 'r'; + values[i] = (Datum) NULL; + } + i = 0; + values[i++] = ObjectIdGetDatum(oid); + values[i++] = (Datum) fmgr(F_TEXTIN, comment); + } + + /*** Now, open pg_description and attempt to find the old tuple ***/ + + ScanKeyEntryInitialize(&entry, 0x0, Anum_pg_description_objoid, F_OIDEQ, + ObjectIdGetDatum(oid)); + scan = heap_beginscan(description, false, SnapshotNow, 1, &entry); + searchtuple = heap_getnext(scan, 0); + + /*** If a previous tuple exists, either delete or prep replacement ***/ + + if (HeapTupleIsValid(searchtuple)) + { + + /*** If the comment is blank, call heap_delete, else heap_update ***/ + + if ((comment == NULL) || (strlen(comment) == 0)) + heap_delete(description, &searchtuple->t_self, NULL); + else + { + desctuple = heap_modifytuple(searchtuple, description, values, + nulls, replaces); + heap_update(description, &searchtuple->t_self, desctuple, NULL); + modified = TRUE; + } + } + else + { + + /*** Only if comment is non-blank do we form a new tuple ***/ + + if ((comment != NULL) && (strlen(comment) > 0)) + { + desctuple = heap_formtuple(tupDesc, values, nulls); + heap_insert(description, desctuple); + modified = TRUE; + } - } + } - /*** Complete the scan, update indices, if necessary ***/ + /*** Complete the scan, update indices, if necessary ***/ - heap_endscan(scan); + heap_endscan(scan); - if (modified) { - if (RelationGetForm(description)->relhasindex) { - Relation idescs[Num_pg_description_indices]; + if (modified) + { + if (RelationGetForm(description)->relhasindex) + { + Relation idescs[Num_pg_description_indices]; - CatalogOpenIndices(Num_pg_description_indices, - Name_pg_description_indices, idescs); - CatalogIndexInsert(idescs, Num_pg_description_indices, description, - desctuple); - CatalogCloseIndices(Num_pg_description_indices, idescs); - } - heap_freetuple(desctuple); + CatalogOpenIndices(Num_pg_description_indices, + Name_pg_description_indices, idescs); + CatalogIndexInsert(idescs, Num_pg_description_indices, description, + desctuple); + CatalogCloseIndices(Num_pg_description_indices, idescs); + } + heap_freetuple(desctuple); - } + } - heap_close(description, RowExclusiveLock); + heap_close(description, RowExclusiveLock); } @@ -214,34 +229,35 @@ void CreateComments(Oid oid, char *comment) { *------------------------------------------------------------------ */ -void DeleteComments(Oid oid) { +void +DeleteComments(Oid oid) +{ - Relation description; - TupleDesc tupDesc; - ScanKeyData entry; - HeapScanDesc scan; - HeapTuple searchtuple; + Relation description; + TupleDesc tupDesc; + ScanKeyData entry; + HeapScanDesc scan; + HeapTuple searchtuple; - description = heap_openr(DescriptionRelationName, RowExclusiveLock); - tupDesc = description->rd_att; + description = heap_openr(DescriptionRelationName, RowExclusiveLock); + tupDesc = description->rd_att; - /*** Now, open pg_description and attempt to find the old tuple ***/ + /*** Now, open pg_description and attempt to find the old tuple ***/ - ScanKeyEntryInitialize(&entry, 0x0, Anum_pg_description_objoid, F_OIDEQ, - ObjectIdGetDatum(oid)); - scan = heap_beginscan(description, false, SnapshotNow, 1, &entry); - searchtuple = heap_getnext(scan, 0); + ScanKeyEntryInitialize(&entry, 0x0, Anum_pg_description_objoid, F_OIDEQ, + ObjectIdGetDatum(oid)); + scan = heap_beginscan(description, false, SnapshotNow, 1, &entry); + searchtuple = heap_getnext(scan, 0); - /*** If a previous tuple exists, delete it ***/ + /*** If a previous tuple exists, delete it ***/ - if (HeapTupleIsValid(searchtuple)) { - heap_delete(description, &searchtuple->t_self, NULL); - } + if (HeapTupleIsValid(searchtuple)) + heap_delete(description, &searchtuple->t_self, NULL); - /*** Complete the scan, update indices, if necessary ***/ + /*** Complete the scan, update indices, if necessary ***/ - heap_endscan(scan); - heap_close(description, RowExclusiveLock); + heap_endscan(scan); + heap_close(description, RowExclusiveLock); } @@ -256,60 +272,57 @@ void DeleteComments(Oid oid) { *------------------------------------------------------------------ */ -static void CommentRelation(int reltype, char *relname, char *comment) { - - HeapTuple reltuple; - Oid oid; - char relkind; - - /*** First, check object security ***/ - - #ifndef NO_SECURITY - if (!pg_ownercheck(GetPgUserName(), relname, RELNAME)) { - elog(ERROR, "you are not permitted to comment on class '%s'", relname); - } - #endif - - /*** Now, attempt to find the oid in the cached version of pg_class ***/ - - reltuple = SearchSysCacheTuple(RELNAME, PointerGetDatum(relname), - 0, 0, 0); - if (!HeapTupleIsValid(reltuple)) { - elog(ERROR, "relation '%s' does not exist", relname); - } - - oid = reltuple->t_data->t_oid; - - /*** Next, verify that the relation type matches the intent ***/ - - relkind = ((Form_pg_class) GETSTRUCT(reltuple))->relkind; - - switch (reltype) { - case (INDEX): - if (relkind != 'i') { - elog(ERROR, "relation '%s' is not an index", relname); - } - break; - case (TABLE): - if (relkind != 'r') { - elog(ERROR, "relation '%s' is not a table", relname); - } - break; - case (VIEW): - if (relkind != 'r') { - elog(ERROR, "relation '%s' is not a view", relname); - } - break; - case (SEQUENCE): - if (relkind != 'S') { - elog(ERROR, "relation '%s' is not a sequence", relname); - } - break; - } - - /*** Create the comments using the tuple's oid ***/ - - CreateComments(oid, comment); +static void +CommentRelation(int reltype, char *relname, char *comment) +{ + + HeapTuple reltuple; + Oid oid; + char relkind; + + /*** First, check object security ***/ + +#ifndef NO_SECURITY + if (!pg_ownercheck(GetPgUserName(), relname, RELNAME)) + elog(ERROR, "you are not permitted to comment on class '%s'", relname); +#endif + + /*** Now, attempt to find the oid in the cached version of pg_class ***/ + + reltuple = SearchSysCacheTuple(RELNAME, PointerGetDatum(relname), + 0, 0, 0); + if (!HeapTupleIsValid(reltuple)) + elog(ERROR, "relation '%s' does not exist", relname); + + oid = reltuple->t_data->t_oid; + + /*** Next, verify that the relation type matches the intent ***/ + + relkind = ((Form_pg_class) GETSTRUCT(reltuple))->relkind; + + switch (reltype) + { + case (INDEX): + if (relkind != 'i') + elog(ERROR, "relation '%s' is not an index", relname); + break; + case (TABLE): + if (relkind != 'r') + elog(ERROR, "relation '%s' is not a table", relname); + break; + case (VIEW): + if (relkind != 'r') + elog(ERROR, "relation '%s' is not a view", relname); + break; + case (SEQUENCE): + if (relkind != 'S') + elog(ERROR, "relation '%s' is not a sequence", relname); + break; + } + + /*** Create the comments using the tuple's oid ***/ + + CreateComments(oid, comment); } @@ -320,43 +333,45 @@ static void CommentRelation(int reltype, char *relname, char *comment) { * such as a table's column. The routine will check security * restrictions and then attempt to fetch the oid of the associated * attribute. If successful, a comment is added/dropped, else an - * elog() exception is thrown. The parameters are the relation + * elog() exception is thrown. The parameters are the relation * and attribute names, and the comments *------------------------------------------------------------------ */ -static void CommentAttribute(char *relname, char *attrname, char *comment) { +static void +CommentAttribute(char *relname, char *attrname, char *comment) +{ - Relation relation; - HeapTuple attrtuple; - Oid oid; + Relation relation; + HeapTuple attrtuple; + Oid oid; - /*** First, check object security ***/ + /*** First, check object security ***/ - #ifndef NO_SECURITY - if (!pg_ownercheck(GetPgUserName(), relname, RELNAME)) { - elog(ERROR, "you are not permitted to comment on class '%s\'", relname); - } - #endif +#ifndef NO_SECURITY + if (!pg_ownercheck(GetPgUserName(), relname, RELNAME)) + elog(ERROR, "you are not permitted to comment on class '%s\'", relname); +#endif - /*** Now, fetch the attribute oid from the system cache ***/ + /*** Now, fetch the attribute oid from the system cache ***/ - relation = heap_openr(relname, AccessShareLock); - attrtuple = SearchSysCacheTuple(ATTNAME, ObjectIdGetDatum(relation->rd_id), - PointerGetDatum(attrname), 0, 0); - if (!HeapTupleIsValid(attrtuple)) { - elog(ERROR, "'%s' is not an attribute of class '%s'", - attrname, relname); - } - oid = attrtuple->t_data->t_oid; + relation = heap_openr(relname, AccessShareLock); + attrtuple = SearchSysCacheTuple(ATTNAME, ObjectIdGetDatum(relation->rd_id), + PointerGetDatum(attrname), 0, 0); + if (!HeapTupleIsValid(attrtuple)) + { + elog(ERROR, "'%s' is not an attribute of class '%s'", + attrname, relname); + } + oid = attrtuple->t_data->t_oid; - /*** Call CreateComments() to create/drop the comments ***/ + /*** Call CreateComments() to create/drop the comments ***/ - CreateComments(oid, comment); + CreateComments(oid, comment); - /*** Now, close the heap relation and return ***/ + /*** Now, close the heap relation and return ***/ - heap_close(relation, AccessShareLock); + heap_close(relation, AccessShareLock); } @@ -371,61 +386,64 @@ static void CommentAttribute(char *relname, char *attrname, char *comment) { *------------------------------------------------------------------ */ -static void CommentDatabase(char *database, char *comment) { +static void +CommentDatabase(char *database, char *comment) +{ - Relation pg_database; - HeapTuple dbtuple, usertuple; - ScanKeyData entry; - HeapScanDesc scan; - Oid oid; - bool superuser; - int4 dba, userid; - char *username; + Relation pg_database; + HeapTuple dbtuple, + usertuple; + ScanKeyData entry; + HeapScanDesc scan; + Oid oid; + bool superuser; + int4 dba, + userid; + char *username; - /*** First find the tuple in pg_database for the database ***/ + /*** First find the tuple in pg_database for the database ***/ - pg_database = heap_openr(DatabaseRelationName, AccessShareLock); - ScanKeyEntryInitialize(&entry, 0, Anum_pg_database_datname, - F_NAMEEQ, NameGetDatum(database)); - scan = heap_beginscan(pg_database, 0, SnapshotNow, 1, &entry); - dbtuple = heap_getnext(scan, 0); + pg_database = heap_openr(DatabaseRelationName, AccessShareLock); + ScanKeyEntryInitialize(&entry, 0, Anum_pg_database_datname, + F_NAMEEQ, NameGetDatum(database)); + scan = heap_beginscan(pg_database, 0, SnapshotNow, 1, &entry); + dbtuple = heap_getnext(scan, 0); - /*** Validate database exists, and fetch the dba id and oid ***/ + /*** Validate database exists, and fetch the dba id and oid ***/ - if (!HeapTupleIsValid(dbtuple)) { - elog(ERROR, "database '%s' does not exist", database); - } - dba = ((Form_pg_database) GETSTRUCT(dbtuple))->datdba; - oid = dbtuple->t_data->t_oid; + if (!HeapTupleIsValid(dbtuple)) + elog(ERROR, "database '%s' does not exist", database); + dba = ((Form_pg_database) GETSTRUCT(dbtuple))->datdba; + oid = dbtuple->t_data->t_oid; - /*** Now, fetch user information ***/ + /*** Now, fetch user information ***/ - username = GetPgUserName(); - usertuple = SearchSysCacheTuple(SHADOWNAME, PointerGetDatum(username), - 0, 0, 0); - if (!HeapTupleIsValid(usertuple)) { - elog(ERROR, "current user '%s' does not exist", username); - } - userid = ((Form_pg_shadow) GETSTRUCT(usertuple))->usesysid; - superuser = ((Form_pg_shadow) GETSTRUCT(usertuple))->usesuper; + username = GetPgUserName(); + usertuple = SearchSysCacheTuple(SHADOWNAME, PointerGetDatum(username), + 0, 0, 0); + if (!HeapTupleIsValid(usertuple)) + elog(ERROR, "current user '%s' does not exist", username); + userid = ((Form_pg_shadow) GETSTRUCT(usertuple))->usesysid; + superuser = ((Form_pg_shadow) GETSTRUCT(usertuple))->usesuper; - /*** Allow if the userid matches the database dba or is a superuser ***/ + /*** Allow if the userid matches the database dba or is a superuser ***/ - #ifndef NO_SECURITY - if (!(superuser || (userid == dba))) { - elog(ERROR, "you are not permitted to comment on database '%s'", - database); - } - #endif +#ifndef NO_SECURITY + if (!(superuser || (userid == dba))) + { + elog(ERROR, "you are not permitted to comment on database '%s'", + database); + } +#endif - /*** Create the comments with the pg_database oid ***/ + /*** Create the comments with the pg_database oid ***/ - CreateComments(oid, comment); + CreateComments(oid, comment); - /*** Complete the scan and close any opened relations ***/ + /*** Complete the scan and close any opened relations ***/ - heap_endscan(scan); - heap_close(pg_database, AccessShareLock); + heap_endscan(scan); + heap_close(pg_database, AccessShareLock); } @@ -439,38 +457,41 @@ static void CommentDatabase(char *database, char *comment) { *------------------------------------------------------------------ */ -static void CommentRewrite(char *rule, char *comment) { +static void +CommentRewrite(char *rule, char *comment) +{ - HeapTuple rewritetuple; - Oid oid; - char *user, *relation; - int aclcheck; + HeapTuple rewritetuple; + Oid oid; + char *user, + *relation; + int aclcheck; - /*** First, validate user ***/ + /*** First, validate user ***/ - #ifndef NO_SECURITY - user = GetPgUserName(); - relation = RewriteGetRuleEventRel(rule); - aclcheck = pg_aclcheck(relation, user, ACL_RU); - if (aclcheck != ACLCHECK_OK) { - elog(ERROR, "you are not permitted to comment on rule '%s'", - rule); - } - #endif +#ifndef NO_SECURITY + user = GetPgUserName(); + relation = RewriteGetRuleEventRel(rule); + aclcheck = pg_aclcheck(relation, user, ACL_RU); + if (aclcheck != ACLCHECK_OK) + { + elog(ERROR, "you are not permitted to comment on rule '%s'", + rule); + } +#endif - /*** Next, find the rule's oid ***/ + /*** Next, find the rule's oid ***/ - rewritetuple = SearchSysCacheTuple(RULENAME, PointerGetDatum(rule), - 0, 0, 0); - if (!HeapTupleIsValid(rewritetuple)) { - elog(ERROR, "rule '%s' does not exist", rule); - } + rewritetuple = SearchSysCacheTuple(RULENAME, PointerGetDatum(rule), + 0, 0, 0); + if (!HeapTupleIsValid(rewritetuple)) + elog(ERROR, "rule '%s' does not exist", rule); - oid = rewritetuple->t_data->t_oid; + oid = rewritetuple->t_data->t_oid; - /*** Call CreateComments() to create/drop the comments ***/ + /*** Call CreateComments() to create/drop the comments ***/ - CreateComments(oid, comment); + CreateComments(oid, comment); } @@ -485,35 +506,37 @@ static void CommentRewrite(char *rule, char *comment) { *------------------------------------------------------------------ */ -static void CommentType(char *type, char *comment) { +static void +CommentType(char *type, char *comment) +{ - HeapTuple typetuple; - Oid oid; - char *user; + HeapTuple typetuple; + Oid oid; + char *user; - /*** First, validate user ***/ + /*** First, validate user ***/ - #ifndef NO_SECURITY - user = GetPgUserName(); - if (!pg_ownercheck(user, type, TYPENAME)) { - elog(ERROR, "you are not permitted to comment on type '%s'", - type); - } - #endif +#ifndef NO_SECURITY + user = GetPgUserName(); + if (!pg_ownercheck(user, type, TYPENAME)) + { + elog(ERROR, "you are not permitted to comment on type '%s'", + type); + } +#endif - /*** Next, find the type's oid ***/ + /*** Next, find the type's oid ***/ - typetuple = SearchSysCacheTuple(TYPENAME, PointerGetDatum(type), - 0, 0, 0); - if (!HeapTupleIsValid(typetuple)) { - elog(ERROR, "type '%s' does not exist", type); - } + typetuple = SearchSysCacheTuple(TYPENAME, PointerGetDatum(type), + 0, 0, 0); + if (!HeapTupleIsValid(typetuple)) + elog(ERROR, "type '%s' does not exist", type); - oid = typetuple->t_data->t_oid; + oid = typetuple->t_data->t_oid; - /*** Call CreateComments() to create/drop the comments ***/ + /*** Call CreateComments() to create/drop the comments ***/ - CreateComments(oid, comment); + CreateComments(oid, comment); } @@ -527,57 +550,66 @@ static void CommentType(char *type, char *comment) { *------------------------------------------------------------------ */ -static void CommentAggregate(char *aggregate, char *argument, char *comment) { - - HeapTuple aggtuple; - Oid baseoid, oid; - bool defined; - char *user; - - /*** First, attempt to determine the base aggregate oid ***/ - - if (argument) { - baseoid = TypeGet(argument, &defined); - if (!OidIsValid(baseoid)) { - elog(ERROR, "aggregate type '%s' does not exist", argument); - } - } else { - baseoid = 0; - } - - /*** Next, validate the user's attempt to comment ***/ - - #ifndef NO_SECURITY - user = GetPgUserName(); - if (!pg_aggr_ownercheck(user, aggregate, baseoid)) { - if (argument) { - elog(ERROR, "you are not permitted to comment on aggregate '%s' %s '%s'", - aggregate, "with type", argument); - } else { - elog(ERROR, "you are not permitted to comment on aggregate '%s'", - aggregate); - } - } - #endif - - /*** Now, attempt to find the actual tuple in pg_aggregate ***/ - - aggtuple = SearchSysCacheTuple(AGGNAME, PointerGetDatum(aggregate), - ObjectIdGetDatum(baseoid), 0, 0); - if (!HeapTupleIsValid(aggtuple)) { - if (argument) { - elog(ERROR, "aggregate type '%s' does not exist for aggregate '%s'", - argument, aggregate); - } else { - elog(ERROR, "aggregate '%s' does not exist", aggregate); - } - } - - oid = aggtuple->t_data->t_oid; - - /*** Call CreateComments() to create/drop the comments ***/ - - CreateComments(oid, comment); +static void +CommentAggregate(char *aggregate, char *argument, char *comment) +{ + + HeapTuple aggtuple; + Oid baseoid, + oid; + bool defined; + char *user; + + /*** First, attempt to determine the base aggregate oid ***/ + + if (argument) + { + baseoid = TypeGet(argument, &defined); + if (!OidIsValid(baseoid)) + elog(ERROR, "aggregate type '%s' does not exist", argument); + } + else + baseoid = 0; + + /*** Next, validate the user's attempt to comment ***/ + +#ifndef NO_SECURITY + user = GetPgUserName(); + if (!pg_aggr_ownercheck(user, aggregate, baseoid)) + { + if (argument) + { + elog(ERROR, "you are not permitted to comment on aggregate '%s' %s '%s'", + aggregate, "with type", argument); + } + else + { + elog(ERROR, "you are not permitted to comment on aggregate '%s'", + aggregate); + } + } +#endif + + /*** Now, attempt to find the actual tuple in pg_aggregate ***/ + + aggtuple = SearchSysCacheTuple(AGGNAME, PointerGetDatum(aggregate), + ObjectIdGetDatum(baseoid), 0, 0); + if (!HeapTupleIsValid(aggtuple)) + { + if (argument) + { + elog(ERROR, "aggregate type '%s' does not exist for aggregate '%s'", + argument, aggregate); + } + else + elog(ERROR, "aggregate '%s' does not exist", aggregate); + } + + oid = aggtuple->t_data->t_oid; + + /*** Call CreateComments() to create/drop the comments ***/ + + CreateComments(oid, comment); } @@ -592,12 +624,17 @@ static void CommentAggregate(char *aggregate, char *argument, char *comment) { *------------------------------------------------------------------ */ -static void CommentProc(char *function, List *arguments, char *comment) +static void +CommentProc(char *function, List *arguments, char *comment) { - HeapTuple argtuple, functuple; - Oid oid, argoids[FUNC_MAX_ARGS]; - char *user, *argument; - int i, argcount; + HeapTuple argtuple, + functuple; + Oid oid, + argoids[FUNC_MAX_ARGS]; + char *user, + *argument; + int i, + argcount; /*** First, initialize function's argument list with their type oids ***/ @@ -606,13 +643,12 @@ static void CommentProc(char *function, List *arguments, char *comment) if (argcount > FUNC_MAX_ARGS) elog(ERROR, "functions cannot have more than %d arguments", FUNC_MAX_ARGS); - for (i = 0; i < argcount; i++) { + for (i = 0; i < argcount; i++) + { argument = strVal(lfirst(arguments)); arguments = lnext(arguments); if (strcmp(argument, "opaque") == 0) - { argoids[i] = 0; - } else { argtuple = SearchSysCacheTuple(TYPENAME, @@ -623,7 +659,7 @@ static void CommentProc(char *function, List *arguments, char *comment) argument); argoids[i] = argtuple->t_data->t_oid; } - } + } /*** Now, validate the user's ability to comment on this function ***/ @@ -663,81 +699,89 @@ static void CommentProc(char *function, List *arguments, char *comment) *------------------------------------------------------------------ */ -static void CommentOperator(char *opername, List *arguments, char *comment) { - - Form_pg_operator data; - HeapTuple optuple; - Oid oid, leftoid = InvalidOid, rightoid = InvalidOid; - bool defined; - char oprtype = 0, *user, *lefttype = NULL, *righttype = NULL; - - /*** Initialize our left and right argument types ***/ - - if (lfirst(arguments) != NULL) { - lefttype = strVal(lfirst(arguments)); - } - if (lsecond(arguments) != NULL) { - righttype = strVal(lsecond(arguments)); - } +static void +CommentOperator(char *opername, List *arguments, char *comment) +{ - /*** Attempt to fetch the left oid, if specified ***/ + Form_pg_operator data; + HeapTuple optuple; + Oid oid, + leftoid = InvalidOid, + rightoid = InvalidOid; + bool defined; + char oprtype = 0, + *user, + *lefttype = NULL, + *righttype = NULL; + + /*** Initialize our left and right argument types ***/ + + if (lfirst(arguments) != NULL) + lefttype = strVal(lfirst(arguments)); + if (lsecond(arguments) != NULL) + righttype = strVal(lsecond(arguments)); + + /*** Attempt to fetch the left oid, if specified ***/ + + if (lefttype != NULL) + { + leftoid = TypeGet(lefttype, &defined); + if (!OidIsValid(leftoid)) + elog(ERROR, "left type '%s' does not exist", lefttype); + } - if (lefttype != NULL) { - leftoid = TypeGet(lefttype, &defined); - if (!OidIsValid(leftoid)) { - elog(ERROR, "left type '%s' does not exist", lefttype); - } - } + /*** Attempt to fetch the right oid, if specified ***/ - /*** Attempt to fetch the right oid, if specified ***/ + if (righttype != NULL) + { + rightoid = TypeGet(righttype, &defined); + if (!OidIsValid(rightoid)) + elog(ERROR, "right type '%s' does not exist", righttype); + } - if (righttype != NULL) { - rightoid = TypeGet(righttype, &defined); - if (!OidIsValid(rightoid)) { - elog(ERROR, "right type '%s' does not exist", righttype); - } - } + /*** Determine operator type ***/ - /*** Determine operator type ***/ + if (OidIsValid(leftoid) && (OidIsValid(rightoid))) + oprtype = 'b'; + else if (OidIsValid(leftoid)) + oprtype = 'l'; + else if (OidIsValid(rightoid)) + oprtype = 'r'; + else + elog(ERROR, "operator '%s' is of an illegal type'", opername); - if (OidIsValid(leftoid) && (OidIsValid(rightoid))) oprtype = 'b'; - else if (OidIsValid(leftoid)) oprtype = 'l'; - else if (OidIsValid(rightoid)) oprtype = 'r'; - else elog(ERROR, "operator '%s' is of an illegal type'", opername); + /*** Attempt to fetch the operator oid ***/ - /*** Attempt to fetch the operator oid ***/ + optuple = SearchSysCacheTupleCopy(OPERNAME, PointerGetDatum(opername), + ObjectIdGetDatum(leftoid), + ObjectIdGetDatum(rightoid), + CharGetDatum(oprtype)); + if (!HeapTupleIsValid(optuple)) + elog(ERROR, "operator '%s' does not exist", opername); - optuple = SearchSysCacheTupleCopy(OPERNAME, PointerGetDatum(opername), - ObjectIdGetDatum(leftoid), - ObjectIdGetDatum(rightoid), - CharGetDatum(oprtype)); - if (!HeapTupleIsValid(optuple)) { - elog(ERROR, "operator '%s' does not exist", opername); - } + oid = optuple->t_data->t_oid; - oid = optuple->t_data->t_oid; + /*** Valid user's ability to comment on this operator ***/ - /*** Valid user's ability to comment on this operator ***/ +#ifndef NO_SECURITY + user = GetPgUserName(); + if (!pg_ownercheck(user, (char *) ObjectIdGetDatum(oid), OPEROID)) + { + elog(ERROR, "you are not permitted to comment on operator '%s'", + opername); + } +#endif - #ifndef NO_SECURITY - user = GetPgUserName(); - if (!pg_ownercheck(user, (char *) ObjectIdGetDatum(oid), OPEROID)) { - elog(ERROR, "you are not permitted to comment on operator '%s'", - opername); - } - #endif + /*** Get the procedure associated with the operator ***/ - /*** Get the procedure associated with the operator ***/ + data = (Form_pg_operator) GETSTRUCT(optuple); + oid = regproctooid(data->oprcode); + if (oid == InvalidOid) + elog(ERROR, "operator '%s' does not have an underlying function", opername); - data = (Form_pg_operator) GETSTRUCT(optuple); - oid = regproctooid(data->oprcode); - if (oid == InvalidOid) { - elog(ERROR, "operator '%s' does not have an underlying function", opername); - } - - /*** Call CreateComments() to create/drop the comments ***/ + /*** Call CreateComments() to create/drop the comments ***/ - CreateComments(oid, comment); + CreateComments(oid, comment); } @@ -752,58 +796,65 @@ static void CommentOperator(char *opername, List *arguments, char *comment) { *------------------------------------------------------------------ */ -static void CommentTrigger(char *trigger, char *relname, char *comment) { - - Form_pg_trigger data; - Relation pg_trigger, relation; - HeapTuple triggertuple; - HeapScanDesc scan; - ScanKeyData entry; - Oid oid = InvalidOid; - char *user; - - /*** First, validate the user's action ***/ - - #ifndef NO_SECURITY - user = GetPgUserName(); - if (!pg_ownercheck(user, relname, RELNAME)) { - elog(ERROR, "you are not permitted to comment on trigger '%s' %s '%s'", - trigger, "defined for relation", relname); - } - #endif - - /*** Now, fetch the trigger oid from pg_trigger ***/ - - relation = heap_openr(relname, AccessShareLock); - pg_trigger = heap_openr(TriggerRelationName, AccessShareLock); - ScanKeyEntryInitialize(&entry, 0, Anum_pg_trigger_tgrelid, - F_OIDEQ, RelationGetRelid(relation)); - scan = heap_beginscan(pg_trigger, 0, SnapshotNow, 1, &entry); - triggertuple = heap_getnext(scan, 0); - while (HeapTupleIsValid(triggertuple)) { - data = (Form_pg_trigger) GETSTRUCT(triggertuple); - if (namestrcmp(&(data->tgname), trigger) == 0) { - oid = triggertuple->t_data->t_oid; - break; - } - triggertuple = heap_getnext(scan, 0); - } - - /*** If no trigger exists for the relation specified, notify user ***/ - - if (oid == InvalidOid) { - elog(ERROR, "trigger '%s' defined for relation '%s' does not exist", - trigger, relname); - } - - /*** Create the comments with the pg_trigger oid ***/ - - CreateComments(oid, comment); - - /*** Complete the scan and close any opened relations ***/ - - heap_endscan(scan); - heap_close(pg_trigger, AccessShareLock); - heap_close(relation, AccessShareLock); +static void +CommentTrigger(char *trigger, char *relname, char *comment) +{ + + Form_pg_trigger data; + Relation pg_trigger, + relation; + HeapTuple triggertuple; + HeapScanDesc scan; + ScanKeyData entry; + Oid oid = InvalidOid; + char *user; + + /*** First, validate the user's action ***/ + +#ifndef NO_SECURITY + user = GetPgUserName(); + if (!pg_ownercheck(user, relname, RELNAME)) + { + elog(ERROR, "you are not permitted to comment on trigger '%s' %s '%s'", + trigger, "defined for relation", relname); + } +#endif + + /*** Now, fetch the trigger oid from pg_trigger ***/ + + relation = heap_openr(relname, AccessShareLock); + pg_trigger = heap_openr(TriggerRelationName, AccessShareLock); + ScanKeyEntryInitialize(&entry, 0, Anum_pg_trigger_tgrelid, + F_OIDEQ, RelationGetRelid(relation)); + scan = heap_beginscan(pg_trigger, 0, SnapshotNow, 1, &entry); + triggertuple = heap_getnext(scan, 0); + while (HeapTupleIsValid(triggertuple)) + { + data = (Form_pg_trigger) GETSTRUCT(triggertuple); + if (namestrcmp(&(data->tgname), trigger) == 0) + { + oid = triggertuple->t_data->t_oid; + break; + } + triggertuple = heap_getnext(scan, 0); + } + + /*** If no trigger exists for the relation specified, notify user ***/ + + if (oid == InvalidOid) + { + elog(ERROR, "trigger '%s' defined for relation '%s' does not exist", + trigger, relname); + } + + /*** Create the comments with the pg_trigger oid ***/ + + CreateComments(oid, comment); + + /*** Complete the scan and close any opened relations ***/ + + heap_endscan(scan); + heap_close(pg_trigger, AccessShareLock); + heap_close(relation, AccessShareLock); } diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index 8634ab11dd5..7662b9dc28a 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.103 2000/03/23 21:38:58 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.104 2000/04/12 17:14:58 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -64,8 +64,8 @@ static int CountTuples(Relation relation); * Static communication variables ... pretty grotty, but COPY has * never been reentrant... */ -int lineno = 0; /* used by elog() -- dz */ -static bool fe_eof; +int lineno = 0; /* used by elog() -- dz */ +static bool fe_eof; /* * These static variables are used to avoid incurring overhead for each @@ -76,9 +76,11 @@ static bool fe_eof; * to attribute_buf's data buffer! * encoding, if needed, can be set once at the start of the copy operation. */ -static StringInfoData attribute_buf; +static StringInfoData attribute_buf; + #ifdef MULTIBYTE -static int encoding; +static int encoding; + #endif @@ -113,11 +115,11 @@ CopySendData(void *databuf, int datasize, FILE *fp) fe_eof = true; } else - { + { fwrite(databuf, datasize, 1, fp); - if (ferror(fp)) - elog(ERROR, "CopySendData: %s", strerror(errno)); - } + if (ferror(fp)) + elog(ERROR, "CopySendData: %s", strerror(errno)); + } } static void @@ -194,7 +196,8 @@ CopyPeekChar(FILE *fp) { if (!fp) { - int ch = pq_peekbyte(); + int ch = pq_peekbyte(); + if (ch == EOF) fe_eof = true; return ch; @@ -280,15 +283,15 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe, * Open and lock the relation, using the appropriate lock type. * * Note: AccessExclusive is probably overkill for copying to a relation, - * but that's what the code grabs on the rel's indices. If this lock is - * relaxed then I think the index locks need relaxed also. + * but that's what the code grabs on the rel's indices. If this lock + * is relaxed then I think the index locks need relaxed also. */ rel = heap_openr(relname, (from ? AccessExclusiveLock : AccessShareLock)); result = pg_aclcheck(relname, UserName, required_access); if (result != ACLCHECK_OK) elog(ERROR, "%s: %s", relname, aclcheck_error_strings[result]); - if (!pipe && !superuser()) + if (!pipe && !superuser()) elog(ERROR, "You must have Postgres superuser privilege to do a COPY " "directly to or from a file. Anyone can COPY to stdout or " "from stdin. Psql's \\copy command also works for anyone."); @@ -345,13 +348,13 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe, } else { - mode_t oumask; /* Pre-existing umask value */ + mode_t oumask; /* Pre-existing umask value */ - oumask = umask((mode_t) 022); + oumask = umask((mode_t) 022); if (*filename != '/') elog(ERROR, "Relative path not allowed for server side" - " COPY command."); + " COPY command."); #ifndef __CYGWIN32__ fp = AllocateFile(filename, "w"); @@ -369,9 +372,7 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe, } if (!pipe) - { FreeFile(fp); - } else if (!from) { if (!binary) @@ -382,9 +383,10 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe, pfree(attribute_buf.data); /* - * Close the relation. If reading, we can release the AccessShareLock - * we got; if writing, we should hold the lock until end of transaction - * to ensure that updates will be committed before lock is released. + * Close the relation. If reading, we can release the AccessShareLock + * we got; if writing, we should hold the lock until end of + * transaction to ensure that updates will be committed before lock is + * released. */ heap_close(rel, (from ? NoLock : AccessShareLock)); } @@ -399,9 +401,11 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null_p int32 attr_count, i; + #ifdef _DROP_COLUMN_HACK__ - bool *valid; -#endif /* _DROP_COLUMN_HACK__ */ + bool *valid; + +#endif /* _DROP_COLUMN_HACK__ */ Form_pg_attribute *attr; FmgrInfo *out_functions; Oid out_func_oid; @@ -435,7 +439,7 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null_p typmod = (int32 *) palloc(attr_count * sizeof(int32)); #ifdef _DROP_COLUMN_HACK__ valid = (bool *) palloc(attr_count * sizeof(bool)); -#endif /* _DROP_COLUMN_HACK__ */ +#endif /* _DROP_COLUMN_HACK__ */ for (i = 0; i < attr_count; i++) { #ifdef _DROP_COLUMN_HACK__ @@ -446,7 +450,7 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null_p } else valid[i] = true; -#endif /* _DROP_COLUMN_HACK__ */ +#endif /* _DROP_COLUMN_HACK__ */ out_func_oid = (Oid) GetOutputFunction(attr[i]->atttypid); fmgr_info(out_func_oid, &out_functions[i]); elements[i] = GetTypeElement(attr[i]->atttypid); @@ -493,7 +497,7 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null_p CopySendChar('\n', fp); continue; } -#endif /* _DROP_COLUMN_HACK__ */ +#endif /* _DROP_COLUMN_HACK__ */ if (!isnull) { string = (char *) (*fmgr_faddr(&out_functions[i])) @@ -502,7 +506,7 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null_p pfree(string); } else - CopySendString(null_print, fp); /* null indicator */ + CopySendString(null_print, fp); /* null indicator */ if (i == attr_count - 1) CopySendChar('\n', fp); @@ -723,7 +727,7 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null #ifdef _DROP_COLUMN_HACK__ if (COLUMN_IS_DROPPED(attr[i])) continue; -#endif /* _DROP_COLUMN_HACK__ */ +#endif /* _DROP_COLUMN_HACK__ */ in_func_oid = (Oid) GetInputFunction(attr[i]->atttypid); fmgr_info(in_func_oid, &in_functions[i]); elements[i] = GetTypeElement(attr[i]->atttypid); @@ -756,7 +760,7 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null byval[i] = 'n'; continue; } -#endif /* _DROP_COLUMN_HACK__ */ +#endif /* _DROP_COLUMN_HACK__ */ byval[i] = (bool) IsTypeByVal(attr[i]->atttypid); } @@ -765,7 +769,8 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null while (!done) { - if (QueryCancel) { + if (QueryCancel) + { lineno = 0; CancelQuery(); } @@ -796,7 +801,7 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null nulls[i] = 'n'; continue; } -#endif /* _DROP_COLUMN_HACK__ */ +#endif /* _DROP_COLUMN_HACK__ */ string = CopyReadAttribute(fp, &isnull, delim, &newline, null_print); if (isnull) { @@ -937,7 +942,7 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null */ slot->val = tuple; /* SetSlotContents(slot, tuple); */ - if (! ExecQual((List *) indexPred[i], econtext, false)) + if (!ExecQual((List *) indexPred[i], econtext, false)) continue; #endif /* OMIT_PARTIAL_INDEX */ } @@ -1189,6 +1194,7 @@ static char * CopyReadAttribute(FILE *fp, bool *isnull, char *delim, int *newline, char *null_print) { int c; + #ifdef MULTIBYTE int mblen; unsigned char s[2]; @@ -1222,9 +1228,7 @@ CopyReadAttribute(FILE *fp, bool *isnull, char *delim, int *newline, char *null_ break; } if (strchr(delim, c)) - { break; - } if (c == '\\') { c = CopyGetChar(fp); @@ -1272,13 +1276,16 @@ CopyReadAttribute(FILE *fp, bool *isnull, char *delim, int *newline, char *null_ c = val & 0377; } break; - /* This is a special hack to parse `\N' as <backslash-N> - rather then just 'N' to provide compatibility with - the default NULL output. -- pe */ - case 'N': - appendStringInfoCharMacro(&attribute_buf, '\\'); - c = 'N'; - break; + + /* + * This is a special hack to parse `\N' as + * <backslash-N> rather then just 'N' to provide + * compatibility with the default NULL output. -- pe + */ + case 'N': + appendStringInfoCharMacro(&attribute_buf, '\\'); + c = 'N'; + break; case 'b': c = '\b'; break; @@ -1332,8 +1339,8 @@ CopyReadAttribute(FILE *fp, bool *isnull, char *delim, int *newline, char *null_ } #endif - if (strcmp(attribute_buf.data, null_print)==0) - *isnull = true; + if (strcmp(attribute_buf.data, null_print) == 0) + *isnull = true; return attribute_buf.data; @@ -1346,10 +1353,12 @@ CopyAttributeOut(FILE *fp, char *server_string, char *delim) { char *string; char c; + #ifdef MULTIBYTE char *string_start; int mblen; int i; + #endif #ifdef MULTIBYTE diff --git a/src/backend/commands/creatinh.c b/src/backend/commands/creatinh.c index da0fcd479ed..17dbe2cbdff 100644 --- a/src/backend/commands/creatinh.c +++ b/src/backend/commands/creatinh.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.56 2000/01/29 16:58:34 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.57 2000/04/12 17:14:58 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -32,7 +32,7 @@ */ static bool checkAttrExists(const char *attributeName, - const char *attributeType, List *schema); + const char *attributeType, List *schema); static List *MergeAttributes(List *schema, List *supers, List **supconstr); static void StoreCatalogInheritance(Oid relationId, List *supers); @@ -145,14 +145,14 @@ DefineRelation(CreateStmt *stmt, char relkind) StoreCatalogInheritance(relationId, inheritList); /* - * Now add any newly specified column default values - * and CHECK constraints to the new relation. These are passed - * to us in the form of raw parsetrees; we need to transform - * them to executable expression trees before they can be added. - * The most convenient way to do that is to apply the parser's - * transformExpr routine, but transformExpr doesn't work unless - * we have a pre-existing relation. So, the transformation has - * to be postponed to this final step of CREATE TABLE. + * Now add any newly specified column default values and CHECK + * constraints to the new relation. These are passed to us in the + * form of raw parsetrees; we need to transform them to executable + * expression trees before they can be added. The most convenient way + * to do that is to apply the parser's transformExpr routine, but + * transformExpr doesn't work unless we have a pre-existing relation. + * So, the transformation has to be postponed to this final step of + * CREATE TABLE. * * First, scan schema to find new column defaults. */ @@ -181,21 +181,24 @@ DefineRelation(CreateStmt *stmt, char relkind) return; /* - * We must bump the command counter to make the newly-created - * relation tuple visible for opening. + * We must bump the command counter to make the newly-created relation + * tuple visible for opening. */ CommandCounterIncrement(); + /* * Open the new relation. */ rel = heap_openr(relname, AccessExclusiveLock); + /* * Parse and add the defaults/constraints. */ AddRelationRawConstraints(rel, rawDefaults, stmt->constraints); + /* - * Clean up. We keep lock on new relation (although it shouldn't - * be visible to anyone else anyway, until commit). + * Clean up. We keep lock on new relation (although it shouldn't be + * visible to anyone else anyway, until commit). */ heap_close(rel, NoLock); } @@ -220,13 +223,13 @@ RemoveRelation(char *name) /* * TruncateRelation -- - * Removes all the rows from a relation + * Removes all the rows from a relation * * Exceptions: - * BadArg if name is invalid + * BadArg if name is invalid * * Note: - * Rows are removed, indices are truncated and reconstructed. + * Rows are removed, indices are truncated and reconstructed. */ void TruncateRelation(char *name) @@ -284,6 +287,7 @@ MergeAttributes(List *schema, List *supers, List **supconstr) foreach(rest, lnext(entry)) { + /* * check for duplicated names within the new relation */ @@ -352,11 +356,12 @@ MergeAttributes(List *schema, List *supers, List **supconstr) * check validity * */ - if (checkAttrExists(attributeName, attributeType, schema)) - elog(ERROR, "CREATE TABLE: attribute \"%s\" already exists in inherited schema", - attributeName); + if (checkAttrExists(attributeName, attributeType, schema)) + elog(ERROR, "CREATE TABLE: attribute \"%s\" already exists in inherited schema", + attributeName); if (checkAttrExists(attributeName, attributeType, inhSchema)) + /* * this entry already exists */ @@ -499,7 +504,7 @@ StoreCatalogInheritance(Oid relationId, List *supers) if (RelationGetForm(relation)->relhasindex) { Relation idescs[Num_pg_inherits_indices]; - + CatalogOpenIndices(Num_pg_inherits_indices, Name_pg_inherits_indices, idescs); CatalogIndexInsert(idescs, Num_pg_inherits_indices, relation, tuple); CatalogCloseIndices(Num_pg_inherits_indices, idescs); @@ -642,8 +647,9 @@ checkAttrExists(const char *attributeName, const char *attributeType, List *sche { ColumnDef *def = lfirst(s); - if (strcmp(attributeName, def->colname)==0) + if (strcmp(attributeName, def->colname) == 0) { + /* * attribute exists. Make sure the types are the same. */ diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c index d4e88ec2dde..d09973f5402 100644 --- a/src/backend/commands/dbcommands.c +++ b/src/backend/commands/dbcommands.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.52 2000/03/26 18:32:28 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.53 2000/04/12 17:14:58 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -33,9 +33,9 @@ #include "catalog/pg_shadow.h" #include "commands/comment.h" #include "miscadmin.h" -#include "storage/bufmgr.h" /* for DropBuffers */ -#include "storage/fd.h" /* for closeAllVfds */ -#include "storage/sinval.h" /* for DatabaseHasActiveBackends */ +#include "storage/bufmgr.h" /* for DropBuffers */ +#include "storage/fd.h" /* for closeAllVfds */ +#include "storage/sinval.h" /* for DatabaseHasActiveBackends */ #include "utils/builtins.h" #include "utils/elog.h" #include "utils/palloc.h" @@ -45,10 +45,10 @@ /* non-export function prototypes */ static bool -get_user_info(const char *name, int4 *use_sysid, bool *use_super, bool *use_createdb); + get_user_info(const char *name, int4 *use_sysid, bool *use_super, bool *use_createdb); static bool -get_db_info(const char *name, char *dbpath, Oid *dbIdP, int4 *ownerIdP); + get_db_info(const char *name, char *dbpath, Oid *dbIdP, int4 *ownerIdP); @@ -61,99 +61,104 @@ createdb(const char *dbname, const char *dbpath, int encoding) { char buf[2 * MAXPGPATH + 100]; char *loc; - char locbuf[512]; + char locbuf[512]; int4 user_id; - bool use_super, use_createdb; + bool use_super, + use_createdb; Relation pg_database_rel; HeapTuple tuple; - TupleDesc pg_database_dsc; - Datum new_record[Natts_pg_database]; - char new_record_nulls[Natts_pg_database] = { ' ', ' ', ' ', ' ' }; + TupleDesc pg_database_dsc; + Datum new_record[Natts_pg_database]; + char new_record_nulls[Natts_pg_database] = {' ', ' ', ' ', ' '}; - if (!get_user_info(GetPgUserName(), &user_id, &use_super, &use_createdb)) - elog(ERROR, "current user name is invalid"); + if (!get_user_info(GetPgUserName(), &user_id, &use_super, &use_createdb)) + elog(ERROR, "current user name is invalid"); - if (!use_createdb && !use_super) - elog(ERROR, "CREATE DATABASE: permission denied"); + if (!use_createdb && !use_super) + elog(ERROR, "CREATE DATABASE: permission denied"); - if (get_db_info(dbname, NULL, NULL, NULL)) - elog(ERROR, "CREATE DATABASE: database \"%s\" already exists", dbname); + if (get_db_info(dbname, NULL, NULL, NULL)) + elog(ERROR, "CREATE DATABASE: database \"%s\" already exists", dbname); - /* don't call this in a transaction block */ + /* don't call this in a transaction block */ if (IsTransactionBlock()) - elog(ERROR, "CREATE DATABASE: may not be called in a transaction block"); + elog(ERROR, "CREATE DATABASE: may not be called in a transaction block"); /* Generate directory name for the new database */ - if (dbpath == NULL || strcmp(dbpath, dbname)==0) - strcpy(locbuf, dbname); - else - snprintf(locbuf, sizeof(locbuf), "%s/%s", dbpath, dbname); + if (dbpath == NULL || strcmp(dbpath, dbname) == 0) + strcpy(locbuf, dbname); + else + snprintf(locbuf, sizeof(locbuf), "%s/%s", dbpath, dbname); - loc = ExpandDatabasePath(locbuf); + loc = ExpandDatabasePath(locbuf); if (loc == NULL) elog(ERROR, - "The database path '%s' is invalid. " + "The database path '%s' is invalid. " "This may be due to a character that is not allowed or because the chosen " - "path isn't permitted for databases", dbpath); + "path isn't permitted for databases", dbpath); - /* close virtual file descriptors so the kernel has more available for - the system() calls */ + /* + * close virtual file descriptors so the kernel has more available for + * the system() calls + */ closeAllVfds(); - /* - * Insert a new tuple into pg_database - */ + /* + * Insert a new tuple into pg_database + */ pg_database_rel = heap_openr(DatabaseRelationName, AccessExclusiveLock); pg_database_dsc = RelationGetDescr(pg_database_rel); - /* Form tuple */ - new_record[Anum_pg_database_datname-1] = NameGetDatum(namein(dbname)); - new_record[Anum_pg_database_datdba-1] = Int32GetDatum(user_id); - new_record[Anum_pg_database_encoding-1] = Int32GetDatum(encoding); - new_record[Anum_pg_database_datpath-1] = PointerGetDatum(textin(locbuf)); + /* Form tuple */ + new_record[Anum_pg_database_datname - 1] = NameGetDatum(namein(dbname)); + new_record[Anum_pg_database_datdba - 1] = Int32GetDatum(user_id); + new_record[Anum_pg_database_encoding - 1] = Int32GetDatum(encoding); + new_record[Anum_pg_database_datpath - 1] = PointerGetDatum(textin(locbuf)); - tuple = heap_formtuple(pg_database_dsc, new_record, new_record_nulls); + tuple = heap_formtuple(pg_database_dsc, new_record, new_record_nulls); - /* - * Update table - */ - heap_insert(pg_database_rel, tuple); + /* + * Update table + */ + heap_insert(pg_database_rel, tuple); - /* - * Update indexes (there aren't any currently) - */ + /* + * Update indexes (there aren't any currently) + */ #ifdef Num_pg_database_indices - if (RelationGetForm(pg_database_rel)->relhasindex) { - Relation idescs[Num_pg_database_indices]; - - CatalogOpenIndices(Num_pg_database_indices, - Name_pg_database_indices, idescs); - CatalogIndexInsert(idescs, Num_pg_database_indices, pg_database_rel, - tuple); - CatalogCloseIndices(Num_pg_database_indices, idescs); - } + if (RelationGetForm(pg_database_rel)->relhasindex) + { + Relation idescs[Num_pg_database_indices]; + + CatalogOpenIndices(Num_pg_database_indices, + Name_pg_database_indices, idescs); + CatalogIndexInsert(idescs, Num_pg_database_indices, pg_database_rel, + tuple); + CatalogCloseIndices(Num_pg_database_indices, idescs); + } #endif heap_close(pg_database_rel, NoLock); - /* Copy the template database to the new location */ + /* Copy the template database to the new location */ - if (mkdir(loc, S_IRWXU) != 0) { + if (mkdir(loc, S_IRWXU) != 0) elog(ERROR, "CREATE DATABASE: unable to create database directory '%s': %s", loc, strerror(errno)); - } snprintf(buf, sizeof(buf), "cp %s%cbase%ctemplate1%c* '%s'", DataDir, SEP_CHAR, SEP_CHAR, SEP_CHAR, loc); - if (system(buf) != 0) { - int ret; - snprintf(buf, sizeof(buf), "rm -rf '%s'", loc); - ret = system(buf); - if (ret == 0) - elog(ERROR, "CREATE DATABASE: could not initialize database directory"); - else - elog(ERROR, "CREATE DATABASE: Could not initialize database directory. Delete failed as well"); - } + if (system(buf) != 0) + { + int ret; + + snprintf(buf, sizeof(buf), "rm -rf '%s'", loc); + ret = system(buf); + if (ret == 0) + elog(ERROR, "CREATE DATABASE: could not initialize database directory"); + else + elog(ERROR, "CREATE DATABASE: Could not initialize database directory. Delete failed as well"); + } } @@ -165,18 +170,19 @@ createdb(const char *dbname, const char *dbpath, int encoding) void dropdb(const char *dbname) { - int4 user_id, db_owner; - bool use_super; + int4 user_id, + db_owner; + bool use_super; Oid db_id; char *path, dbpath[MAXPGPATH], buf[MAXPGPATH + 100]; Relation pgdbrel; HeapScanDesc pgdbscan; - ScanKeyData key; + ScanKeyData key; HeapTuple tup; - AssertArg(dbname); + AssertArg(dbname); if (strcmp(dbname, "template1") == 0) elog(ERROR, "DROP DATABASE: May not be executed on the template1 database"); @@ -185,46 +191,49 @@ dropdb(const char *dbname) elog(ERROR, "DROP DATABASE: Cannot be executed on the currently open database"); if (IsTransactionBlock()) - elog(ERROR, "DROP DATABASE: May not be called in a transaction block"); + elog(ERROR, "DROP DATABASE: May not be called in a transaction block"); - if (!get_user_info(GetPgUserName(), &user_id, &use_super, NULL)) - elog(ERROR, "Current user name is invalid"); + if (!get_user_info(GetPgUserName(), &user_id, &use_super, NULL)) + elog(ERROR, "Current user name is invalid"); - if (!get_db_info(dbname, dbpath, &db_id, &db_owner)) - elog(ERROR, "DROP DATABASE: Database \"%s\" does not exist", dbname); + if (!get_db_info(dbname, dbpath, &db_id, &db_owner)) + elog(ERROR, "DROP DATABASE: Database \"%s\" does not exist", dbname); - if (user_id != db_owner && !use_super) - elog(ERROR, "DROP DATABASE: Permission denied"); + if (user_id != db_owner && !use_super) + elog(ERROR, "DROP DATABASE: Permission denied"); path = ExpandDatabasePath(dbpath); if (path == NULL) elog(ERROR, - "The database path '%s' is invalid. " + "The database path '%s' is invalid. " "This may be due to a character that is not allowed or because the chosen " - "path isn't permitted for databases", path); + "path isn't permitted for databases", path); - /* close virtual file descriptors so the kernel has more available for - the system() calls */ + /* + * close virtual file descriptors so the kernel has more available for + * the system() calls + */ closeAllVfds(); /* - * Obtain exclusive lock on pg_database. We need this to ensure - * that no new backend starts up in the target database while we - * are deleting it. (Actually, a new backend might still manage to - * start up, because it will read pg_database without any locking - * to discover the database's OID. But it will detect its error - * in ReverifyMyDatabase and shut down before any serious damage - * is done. See postinit.c.) + * Obtain exclusive lock on pg_database. We need this to ensure that + * no new backend starts up in the target database while we are + * deleting it. (Actually, a new backend might still manage to start + * up, because it will read pg_database without any locking to + * discover the database's OID. But it will detect its error in + * ReverifyMyDatabase and shut down before any serious damage is done. + * See postinit.c.) */ pgdbrel = heap_openr(DatabaseRelationName, AccessExclusiveLock); /* * Check for active backends in the target database. */ - if (DatabaseHasActiveBackends(db_id)) { + if (DatabaseHasActiveBackends(db_id)) + { heap_close(pgdbrel, AccessExclusiveLock); elog(ERROR, "DROP DATABASE: Database \"%s\" is being accessed by other users", dbname); - } + } /* * Find the database's tuple by OID (should be unique, we trust). @@ -238,8 +247,11 @@ dropdb(const char *dbname) if (!HeapTupleIsValid(tup)) { heap_close(pgdbrel, AccessExclusiveLock); - /* This error should never come up since the existence of the - database is checked earlier */ + + /* + * This error should never come up since the existence of the + * database is checked earlier + */ elog(ERROR, "DROP DATABASE: Database \"%s\" doesn't exist despite earlier reports to the contrary", dbname); } @@ -270,7 +282,7 @@ dropdb(const char *dbname) */ snprintf(buf, sizeof(buf), "rm -rf '%s'", path); if (system(buf) != 0) - elog(NOTICE, "DROP DATABASE: The database directory '%s' could not be removed", path); + elog(NOTICE, "DROP DATABASE: The database directory '%s' could not be removed", path); } @@ -285,11 +297,11 @@ get_db_info(const char *name, char *dbpath, Oid *dbIdP, int4 *ownerIdP) Relation relation; HeapTuple tuple; ScanKeyData scanKey; - HeapScanDesc scan; + HeapScanDesc scan; - AssertArg(name); + AssertArg(name); - relation = heap_openr(DatabaseRelationName, AccessExclusiveLock/*???*/); + relation = heap_openr(DatabaseRelationName, AccessExclusiveLock /* ??? */ ); ScanKeyEntryInitialize(&scanKey, 0, Anum_pg_database_datname, F_NAMEEQ, NameGetDatum(name)); @@ -302,76 +314,76 @@ get_db_info(const char *name, char *dbpath, Oid *dbIdP, int4 *ownerIdP) if (HeapTupleIsValid(tuple)) { - text *tmptext; - bool isnull; - - /* oid of the database */ - if (dbIdP) - *dbIdP = tuple->t_data->t_oid; - /* uid of the owner */ - if (ownerIdP) - { - *ownerIdP = (int4) heap_getattr(tuple, - Anum_pg_database_datdba, - RelationGetDescr(relation), - &isnull); - if (isnull) - *ownerIdP = -1; /* hopefully no one has that id already ;) */ - } - /* database path (as registered in pg_database) */ - if (dbpath) - { - tmptext = (text *) heap_getattr(tuple, - Anum_pg_database_datpath, - RelationGetDescr(relation), - &isnull); - - if (!isnull) - { - Assert(VARSIZE(tmptext) - VARHDRSZ < MAXPGPATH); - - strncpy(dbpath, VARDATA(tmptext), VARSIZE(tmptext) - VARHDRSZ); - *(dbpath + VARSIZE(tmptext) - VARHDRSZ) = '\0'; - } - else - strcpy(dbpath, ""); - } + text *tmptext; + bool isnull; + + /* oid of the database */ + if (dbIdP) + *dbIdP = tuple->t_data->t_oid; + /* uid of the owner */ + if (ownerIdP) + { + *ownerIdP = (int4) heap_getattr(tuple, + Anum_pg_database_datdba, + RelationGetDescr(relation), + &isnull); + if (isnull) + *ownerIdP = -1; /* hopefully no one has that id already ;) */ + } + /* database path (as registered in pg_database) */ + if (dbpath) + { + tmptext = (text *) heap_getattr(tuple, + Anum_pg_database_datpath, + RelationGetDescr(relation), + &isnull); + + if (!isnull) + { + Assert(VARSIZE(tmptext) - VARHDRSZ < MAXPGPATH); + + strncpy(dbpath, VARDATA(tmptext), VARSIZE(tmptext) - VARHDRSZ); + *(dbpath + VARSIZE(tmptext) - VARHDRSZ) = '\0'; + } + else + strcpy(dbpath, ""); + } } else - { - if (dbIdP) - *dbIdP = InvalidOid; - } + { + if (dbIdP) + *dbIdP = InvalidOid; + } heap_endscan(scan); /* We will keep the lock on the relation until end of transaction. */ heap_close(relation, NoLock); - return HeapTupleIsValid(tuple); + return HeapTupleIsValid(tuple); } static bool -get_user_info(const char * name, int4 *use_sysid, bool *use_super, bool *use_createdb) +get_user_info(const char *name, int4 *use_sysid, bool *use_super, bool *use_createdb) { - HeapTuple utup; + HeapTuple utup; AssertArg(name); utup = SearchSysCacheTuple(SHADOWNAME, PointerGetDatum(name), 0, 0, 0); - if (!HeapTupleIsValid(utup)) - return false; + if (!HeapTupleIsValid(utup)) + return false; - if (use_sysid) - *use_sysid = ((Form_pg_shadow) GETSTRUCT(utup))->usesysid; - if (use_super) - *use_super = ((Form_pg_shadow) GETSTRUCT(utup))->usesuper; - if (use_createdb) - *use_createdb = ((Form_pg_shadow) GETSTRUCT(utup))->usecreatedb; + if (use_sysid) + *use_sysid = ((Form_pg_shadow) GETSTRUCT(utup))->usesysid; + if (use_super) + *use_super = ((Form_pg_shadow) GETSTRUCT(utup))->usesuper; + if (use_createdb) + *use_createdb = ((Form_pg_shadow) GETSTRUCT(utup))->usecreatedb; - return true; + return true; } diff --git a/src/backend/commands/define.c b/src/backend/commands/define.c index 2090076f2e4..c77b467089b 100644 --- a/src/backend/commands/define.c +++ b/src/backend/commands/define.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.39 2000/04/07 13:39:24 thomas Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.40 2000/04/12 17:14:58 momjian Exp $ * * DESCRIPTION * The "DefineFoo" routines take the parse tree and pick out the @@ -137,12 +137,13 @@ compute_full_attributes(List *parameters, int32 *byte_pct_p, foreach(pl, parameters) { - DefElem *param = (DefElem *) lfirst(pl); + DefElem *param = (DefElem *) lfirst(pl); if (strcasecmp(param->defname, "iscachable") == 0) *canCache_p = true; else if (strcasecmp(param->defname, "trusted") == 0) { + /* * we don't have untrusted functions any more. The 4.2 * implementation is lousy anyway so I took it out. -ay 10/94 @@ -233,12 +234,14 @@ CreateFunction(ProcedureStmt *stmt, CommandDest dest) */ bool returnsSet; + /* The function returns a set of values, as opposed to a singleton. */ bool lanisPL = false; /* - * The following are optional user-supplied attributes of the function. + * The following are optional user-supplied attributes of the + * function. */ int32 byte_pct, perbyte_cpu, @@ -256,7 +259,7 @@ CreateFunction(ProcedureStmt *stmt, CommandDest dest) elog(ERROR, "Only users with Postgres superuser privilege are " "permitted to create a function " - "in the '%s' language. Others may use the 'sql' language " + "in the '%s' language. Others may use the 'sql' language " "or the created procedural languages.", languageName); } @@ -316,17 +319,17 @@ CreateFunction(ProcedureStmt *stmt, CommandDest dest) interpret_AS_clause(languageName, stmt->as, &prosrc_str, &probin_str); /* - * And now that we have all the parameters, and know we're - * permitted to do so, go ahead and create the function. + * And now that we have all the parameters, and know we're permitted + * to do so, go ahead and create the function. */ ProcedureCreate(stmt->funcname, returnsSet, prorettype, languageName, - prosrc_str, /* converted to text later */ - probin_str, /* converted to text later */ + prosrc_str, /* converted to text later */ + probin_str, /* converted to text later */ canCache, - true, /* (obsolete "trusted") */ + true, /* (obsolete "trusted") */ byte_pct, perbyte_cpu, percall_cpu, @@ -378,7 +381,7 @@ DefineOperator(char *oprName, if (!strcasecmp(defel->defname, "leftarg")) { if ((nodeTag(defel->arg) == T_TypeName) - && (((TypeName *)defel->arg)->setof)) + && (((TypeName *) defel->arg)->setof)) elog(ERROR, "setof type not implemented for leftarg"); typeName1 = defGetString(defel); @@ -388,7 +391,7 @@ DefineOperator(char *oprName, else if (!strcasecmp(defel->defname, "rightarg")) { if ((nodeTag(defel->arg) == T_TypeName) - && (((TypeName *)defel->arg)->setof)) + && (((TypeName *) defel->arg)->setof)) elog(ERROR, "setof type not implemented for rightarg"); typeName2 = defGetString(defel); @@ -698,16 +701,16 @@ DefineType(char *typeName, List *parameters) static char * defGetString(DefElem *def) { - char *string; + char *string; if (nodeTag(def->arg) == T_String) string = strVal(def->arg); else if (nodeTag(def->arg) == T_TypeName) - string = ((TypeName *)def->arg)->name; + string = ((TypeName *) def->arg)->name; else string = NULL; #if 0 - elog(ERROR, "Define: \"%s\" = what?", def->defname); + elog(ERROR, "Define: \"%s\" = what?", def->defname); #endif return string; diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c index 64dc164a0d5..d51053c20a1 100644 --- a/src/backend/commands/explain.c +++ b/src/backend/commands/explain.c @@ -5,7 +5,7 @@ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994-5, Regents of the University of California * - * $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.55 2000/03/14 23:06:12 thomas Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.56 2000/04/12 17:14:58 momjian Exp $ * */ @@ -209,7 +209,7 @@ explain_outNode(StringInfo str, Plan *plan, int indent, ExplainState *es) switch (nodeTag(plan)) { case T_IndexScan: - if (ScanDirectionIsBackward(((IndexScan *)plan)->indxorderdir)) + if (ScanDirectionIsBackward(((IndexScan *) plan)->indxorderdir)) appendStringInfo(str, " Backward"); appendStringInfo(str, " using "); i = 0; @@ -219,7 +219,7 @@ explain_outNode(StringInfo str, Plan *plan, int indent, ExplainState *es) Assert(relation); appendStringInfo(str, "%s%s", (++i > 1) ? ", " : "", - stringStringInfo(RelationGetRelationName(relation))); + stringStringInfo(RelationGetRelationName(relation))); /* drop relcache refcount from RelationIdGetRelation */ RelationDecrementReferenceCount(relation); } @@ -238,17 +238,17 @@ explain_outNode(StringInfo str, Plan *plan, int indent, ExplainState *es) || (length(rte->ref->attrs) > 0)) { appendStringInfo(str, " %s", - stringStringInfo(rte->ref->relname)); + stringStringInfo(rte->ref->relname)); if (length(rte->ref->attrs) > 0) { - List *c; - int firstEntry = true; + List *c; + int firstEntry = true; appendStringInfo(str, " ("); - foreach (c, rte->ref->attrs) + foreach(c, rte->ref->attrs) { - if (! firstEntry) + if (!firstEntry) { appendStringInfo(str, ", "); firstEntry = false; diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index 93ad0eb63b4..2577e4741b1 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.22 2000/02/25 02:58:48 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.23 2000/04/12 17:14:58 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -34,9 +34,9 @@ #include "parser/parse_func.h" #include "utils/builtins.h" #include "utils/syscache.h" -#include "miscadmin.h" /* ReindexDatabase() */ -#include "utils/portal.h" /* ReindexDatabase() */ -#include "catalog/catalog.h" /* ReindexDatabase() */ +#include "miscadmin.h" /* ReindexDatabase() */ +#include "utils/portal.h" /* ReindexDatabase() */ +#include "catalog/catalog.h" /* ReindexDatabase() */ #define IsFuncIndex(ATTR_LIST) (((IndexElem*)lfirst(ATTR_LIST))->args != NIL) @@ -45,11 +45,11 @@ static void CheckPredicate(List *predList, List *rangeTable, Oid baseRelOid); static void CheckPredExpr(Node *predicate, List *rangeTable, Oid baseRelOid); static void CheckPredClause(Expr *predicate, List *rangeTable, Oid baseRelOid); static void FuncIndexArgs(IndexElem *funcIndex, FuncIndexInfo *funcInfo, - AttrNumber *attNumP, Oid *opOidP, Oid relId); + AttrNumber *attNumP, Oid *opOidP, Oid relId); static void NormIndexAttrs(List *attList, AttrNumber *attNumP, - Oid *opOidP, Oid relId); + Oid *opOidP, Oid relId); static void ProcessAttrTypename(IndexElem *attribute, - Oid defType, int32 defTypmod); + Oid defType, int32 defTypmod); static Oid GetAttrOpClass(IndexElem *attribute, Oid attrType); static char *GetDefaultOpClass(Oid atttypid); @@ -133,7 +133,7 @@ DefineIndex(char *heapRelationName, */ foreach(pl, parameterList) { - DefElem *param = (DefElem *) lfirst(pl); + DefElem *param = (DefElem *) lfirst(pl); if (!strcasecmp(param->defname, "islossy")) lossy = TRUE; @@ -174,7 +174,7 @@ DefineIndex(char *heapRelationName, namestrcpy(&fInfo.funcName, funcIndex->name); attributeNumberA = (AttrNumber *) palloc(nargs * - sizeof attributeNumberA[0]); + sizeof attributeNumberA[0]); classObjectId = (Oid *) palloc(sizeof(Oid)); @@ -192,7 +192,7 @@ DefineIndex(char *heapRelationName, else { attributeNumberA = (AttrNumber *) palloc(numberOfAttributes * - sizeof attributeNumberA[0]); + sizeof attributeNumberA[0]); classObjectId = (Oid *) palloc(numberOfAttributes * sizeof(Oid)); @@ -490,7 +490,7 @@ NormIndexAttrs(List *attList, /* list of IndexElem's */ atttuple = SearchSysCacheTupleCopy(ATTNAME, ObjectIdGetDatum(relId), - PointerGetDatum(attribute->name), + PointerGetDatum(attribute->name), 0, 0); if (!HeapTupleIsValid(atttuple)) elog(ERROR, "DefineIndex: attribute \"%s\" not found", @@ -608,7 +608,7 @@ RemoveIndex(char *name) * ... */ void -ReindexIndex(const char *name, bool force /* currently unused */) +ReindexIndex(const char *name, bool force /* currently unused */ ) { HeapTuple tuple; @@ -667,28 +667,35 @@ ReindexTable(const char *name, bool force) * "ERROR" if table nonexistent. * ... */ -extern Oid MyDatabaseId; +extern Oid MyDatabaseId; void ReindexDatabase(const char *dbname, bool force, bool all) { - Relation relation, relationRelation; - HeapTuple usertuple, dbtuple, tuple; - HeapScanDesc scan; - int4 user_id, db_owner; + Relation relation, + relationRelation; + HeapTuple usertuple, + dbtuple, + tuple; + HeapScanDesc scan; + int4 user_id, + db_owner; bool superuser; - Oid db_id; - char *username; - ScanKeyData scankey; - PortalVariableMemory pmem; - MemoryContext old; - int relcnt, relalc, i, oncealc = 200; - Oid *relids = (Oid *) NULL; + Oid db_id; + char *username; + ScanKeyData scankey; + PortalVariableMemory pmem; + MemoryContext old; + int relcnt, + relalc, + i, + oncealc = 200; + Oid *relids = (Oid *) NULL; AssertArg(dbname); username = GetPgUserName(); usertuple = SearchSysCacheTuple(SHADOWNAME, PointerGetDatum(username), - 0, 0, 0); + 0, 0, 0); if (!HeapTupleIsValid(usertuple)) elog(ERROR, "Current user '%s' is invalid.", username); user_id = ((Form_pg_shadow) GETSTRUCT(usertuple))->usesysid; @@ -696,7 +703,7 @@ ReindexDatabase(const char *dbname, bool force, bool all) relation = heap_openr(DatabaseRelationName, AccessShareLock); ScanKeyEntryInitialize(&scankey, 0, Anum_pg_database_datname, - F_NAMEEQ, NameGetDatum(dbname)); + F_NAMEEQ, NameGetDatum(dbname)); scan = heap_beginscan(relation, 0, SnapshotNow, 1, &scankey); dbtuple = heap_getnext(scan, 0); if (!HeapTupleIsValid(dbtuple)) diff --git a/src/backend/commands/remove.c b/src/backend/commands/remove.c index dfcad83c3a8..45d1d310e78 100644 --- a/src/backend/commands/remove.c +++ b/src/backend/commands/remove.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.45 2000/01/26 05:56:13 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.46 2000/04/12 17:14:59 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -156,14 +156,15 @@ SingleOpOperatorRemove(Oid typeOid) { key[0].sk_attno = attnums[i]; scan = heap_beginscan(rel, 0, SnapshotNow, 1, key); - while (HeapTupleIsValid(tup = heap_getnext(scan, 0))) { + while (HeapTupleIsValid(tup = heap_getnext(scan, 0))) + { - /*** This is apparently a routine not in use, but remove ***/ - /*** any comments anyways ***/ + /*** This is apparently a routine not in use, but remove ***/ + /*** any comments anyways ***/ - DeleteComments(tup->t_data->t_oid); + DeleteComments(tup->t_data->t_oid); - heap_delete(rel, &tup->t_self, NULL); + heap_delete(rel, &tup->t_self, NULL); } diff --git a/src/backend/commands/rename.c b/src/backend/commands/rename.c index 454b2d0d93d..6a9c92b1e63 100644 --- a/src/backend/commands/rename.c +++ b/src/backend/commands/rename.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/Attic/rename.c,v 1.41 2000/01/26 05:56:13 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/Attic/rename.c,v 1.42 2000/04/12 17:14:59 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -76,12 +76,12 @@ renameatt(char *relname, #endif /* - * Grab an exclusive lock on the target table, which we will NOT release - * until end of transaction. + * Grab an exclusive lock on the target table, which we will NOT + * release until end of transaction. */ targetrelation = heap_openr(relname, AccessExclusiveLock); relid = RelationGetRelid(targetrelation); - heap_close(targetrelation, NoLock); /* close rel but keep lock! */ + heap_close(targetrelation, NoLock); /* close rel but keep lock! */ /* * if the 'recurse' flag is set then we are supposed to rename this @@ -160,11 +160,12 @@ renameatt(char *relname, /* keep system catalog indices current */ { Relation irelations[Num_pg_attr_indices]; + CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, irelations); CatalogIndexInsert(irelations, Num_pg_attr_indices, attrelation, oldatttup); CatalogCloseIndices(Num_pg_attr_indices, irelations); } - + heap_freetuple(oldatttup); heap_close(attrelation, RowExclusiveLock); } @@ -194,8 +195,8 @@ renamerel(const char *oldrelname, const char *newrelname) newrelname); /* - * Grab an exclusive lock on the target table, which we will NOT release - * until end of transaction. + * Grab an exclusive lock on the target table, which we will NOT + * release until end of transaction. */ targetrelation = heap_openr(oldrelname, AccessExclusiveLock); @@ -211,14 +212,15 @@ renamerel(const char *oldrelname, const char *newrelname) * they don't exist anyway. So, no warning in that case. * ---------------- */ - if (IsTransactionBlock() && ! targetrelation->rd_myxactonly) + if (IsTransactionBlock() && !targetrelation->rd_myxactonly) elog(NOTICE, "Caution: RENAME TABLE cannot be rolled back, so don't abort now"); /* - * Flush all blocks of the relation out of the buffer pool. We need this - * because the blocks are marked with the relation's name as well as OID. - * If some backend tries to write a dirty buffer with mdblindwrt after - * we've renamed the physical file, we'll be in big trouble. + * Flush all blocks of the relation out of the buffer pool. We need + * this because the blocks are marked with the relation's name as well + * as OID. If some backend tries to write a dirty buffer with + * mdblindwrt after we've renamed the physical file, we'll be in big + * trouble. * * Since we hold the exclusive lock on the relation, we don't have to * worry about more blocks being read in while we finish the rename. @@ -227,8 +229,8 @@ renamerel(const char *oldrelname, const char *newrelname) elog(ERROR, "renamerel: unable to flush relation from buffer pool"); /* - * Make sure smgr and lower levels close the relation's files. - * (Next access to rel will reopen them.) + * Make sure smgr and lower levels close the relation's files. (Next + * access to rel will reopen them.) * * Note: we rely on shared cache invalidation message to make other * backends close and re-open the files. @@ -238,14 +240,15 @@ renamerel(const char *oldrelname, const char *newrelname) /* * Close rel, but keep exclusive lock! * - * Note: we don't do anything about updating the relcache entry; - * we assume it will be flushed by shared cache invalidate. - * XXX is this good enough? What if relation is myxactonly? + * Note: we don't do anything about updating the relcache entry; we + * assume it will be flushed by shared cache invalidate. XXX is this + * good enough? What if relation is myxactonly? */ heap_close(targetrelation, NoLock); /* - * Find relation's pg_class tuple, and make sure newrelname isn't in use. + * Find relation's pg_class tuple, and make sure newrelname isn't in + * use. */ relrelation = heap_openr(RelationRelationName, RowExclusiveLock); @@ -262,8 +265,8 @@ renamerel(const char *oldrelname, const char *newrelname) * Perform physical rename of files. If this fails, we haven't yet * done anything irreversible. * - * XXX smgr.c ought to provide an interface for this; doing it - * directly is bletcherous. + * XXX smgr.c ought to provide an interface for this; doing it directly + * is bletcherous. */ strcpy(oldpath, relpath(oldrelname)); strcpy(newpath, relpath(newrelname)); diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c index 23280ec5673..0667297d763 100644 --- a/src/backend/commands/sequence.c +++ b/src/backend/commands/sequence.c @@ -410,7 +410,9 @@ init_sequence(char *caller, char *name) if (elm != (SeqTable) NULL) { - /* We are using a seqtable entry left over from a previous xact; + + /* + * We are using a seqtable entry left over from a previous xact; * must check for relid change. */ elm->rel = seqrel; @@ -424,7 +426,9 @@ init_sequence(char *caller, char *name) } else { - /* Time to make a new seqtable entry. These entries live as long + + /* + * Time to make a new seqtable entry. These entries live as long * as the backend does, so we use plain malloc for them. */ elm = (SeqTable) malloc(sizeof(SeqTableData)); diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index 78df4fd5e8e..9961ce6ff15 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.62 2000/02/29 12:28:24 wieck Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.63 2000/04/12 17:14:59 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -89,7 +89,7 @@ CreateTrigger(CreateTrigStmt *stmt) rel = heap_openr(stmt->constrrelname, NoLock); if (rel == NULL) elog(ERROR, "table \"%s\" does not exist", - stmt->constrrelname); + stmt->constrrelname); constrrelid = rel->rd_id; heap_close(rel, NoLock); } @@ -182,12 +182,12 @@ CreateTrigger(CreateTrigStmt *stmt) values[Anum_pg_trigger_tgfoid - 1] = ObjectIdGetDatum(tuple->t_data->t_oid); values[Anum_pg_trigger_tgtype - 1] = Int16GetDatum(tgtype); - values[Anum_pg_trigger_tgenabled - 1] = true; - values[Anum_pg_trigger_tgisconstraint - 1] = stmt->isconstraint; - values[Anum_pg_trigger_tgconstrname - 1] = PointerGetDatum(constrname);; - values[Anum_pg_trigger_tgconstrrelid - 1] = constrrelid; - values[Anum_pg_trigger_tgdeferrable - 1] = stmt->deferrable; - values[Anum_pg_trigger_tginitdeferred - 1] = stmt->initdeferred; + values[Anum_pg_trigger_tgenabled - 1] = true; + values[Anum_pg_trigger_tgisconstraint - 1] = stmt->isconstraint; + values[Anum_pg_trigger_tgconstrname - 1] = PointerGetDatum(constrname);; + values[Anum_pg_trigger_tgconstrrelid - 1] = constrrelid; + values[Anum_pg_trigger_tgdeferrable - 1] = stmt->deferrable; + values[Anum_pg_trigger_tginitdeferred - 1] = stmt->initdeferred; if (stmt->args) { @@ -261,10 +261,11 @@ CreateTrigger(CreateTrigStmt *stmt) CatalogCloseIndices(Num_pg_class_indices, ridescs); heap_freetuple(tuple); heap_close(pgrel, RowExclusiveLock); + /* * We used to try to update the rel's relcache entry here, but that's - * fairly pointless since it will happen as a byproduct of the upcoming - * CommandCounterIncrement... + * fairly pointless since it will happen as a byproduct of the + * upcoming CommandCounterIncrement... */ /* Keep lock on target rel until end of xact */ heap_close(rel, NoLock); @@ -301,12 +302,12 @@ DropTrigger(DropTrigStmt *stmt) if (namestrcmp(&(pg_trigger->tgname), stmt->trigname) == 0) { - /*** Delete any comments associated with this trigger ***/ + /*** Delete any comments associated with this trigger ***/ - DeleteComments(tuple->t_data->t_oid); + DeleteComments(tuple->t_data->t_oid); - heap_delete(tgrel, &tuple->t_self, NULL); - tgfound++; + heap_delete(tgrel, &tuple->t_self, NULL); + tgfound++; } else @@ -337,10 +338,11 @@ DropTrigger(DropTrigStmt *stmt) CatalogCloseIndices(Num_pg_class_indices, ridescs); heap_freetuple(tuple); heap_close(pgrel, RowExclusiveLock); + /* * We used to try to update the rel's relcache entry here, but that's - * fairly pointless since it will happen as a byproduct of the upcoming - * CommandCounterIncrement... + * fairly pointless since it will happen as a byproduct of the + * upcoming CommandCounterIncrement... */ /* Keep lock on target rel until end of xact */ heap_close(rel, NoLock); @@ -360,13 +362,14 @@ RelationRemoveTriggers(Relation rel) tgscan = heap_beginscan(tgrel, 0, SnapshotNow, 1, &key); - while (HeapTupleIsValid(tup = heap_getnext(tgscan, 0))) { + while (HeapTupleIsValid(tup = heap_getnext(tgscan, 0))) + { - /*** Delete any comments associated with this trigger ***/ + /*** Delete any comments associated with this trigger ***/ - DeleteComments(tup->t_data->t_oid); + DeleteComments(tup->t_data->t_oid); - heap_delete(tgrel, &tup->t_self, NULL); + heap_delete(tgrel, &tup->t_self, NULL); } @@ -385,14 +388,14 @@ RelationRemoveTriggers(Relation rel) * ---------- */ ScanKeyEntryInitialize(&key, 0, Anum_pg_trigger_tgconstrrelid, - F_OIDEQ, RelationGetRelid(rel)); + F_OIDEQ, RelationGetRelid(rel)); tgscan = heap_beginscan(tgrel, 0, SnapshotNow, 1, &key); while (HeapTupleIsValid(tup = heap_getnext(tgscan, 0))) { - Form_pg_trigger pg_trigger; - Relation refrel; - DropTrigStmt stmt; + Form_pg_trigger pg_trigger; + Relation refrel; + DropTrigStmt stmt; pg_trigger = (Form_pg_trigger) GETSTRUCT(tup); @@ -436,8 +439,8 @@ RelationBuildTriggers(Relation relation) Relation irel = (Relation) NULL; ScanKeyData skey; HeapTupleData tuple; - IndexScanDesc sd = (IndexScanDesc) NULL; - HeapScanDesc tgscan = (HeapScanDesc) NULL; + IndexScanDesc sd = (IndexScanDesc) NULL; + HeapScanDesc tgscan = (HeapScanDesc) NULL; HeapTuple htup; RetrieveIndexResult indexRes; Buffer buffer; @@ -684,13 +687,13 @@ FreeTriggerDesc(TriggerDesc *trigdesc) bool equalTriggerDescs(TriggerDesc *trigdesc1, TriggerDesc *trigdesc2) { - int i, - j; + int i, + j; /* - * We need not examine the "index" data, just the trigger array itself; - * if we have the same triggers with the same types, the derived index - * data should match. + * We need not examine the "index" data, just the trigger array + * itself; if we have the same triggers with the same types, the + * derived index data should match. * * XXX It seems possible that the same triggers could appear in different * orders in the two trigger arrays; do we need to handle that? @@ -703,8 +706,8 @@ equalTriggerDescs(TriggerDesc *trigdesc1, TriggerDesc *trigdesc2) return false; for (i = 0; i < trigdesc1->numtriggers; i++) { - Trigger *trig1 = trigdesc1->triggers + i; - Trigger *trig2 = NULL; + Trigger *trig1 = trigdesc1->triggers + i; + Trigger *trig2 = NULL; /* * We can't assume that the triggers are always read from @@ -1014,31 +1017,31 @@ ltrmark:; * end. * ---------- */ -static GlobalMemory deftrig_gcxt = NULL; -static GlobalMemory deftrig_cxt = NULL; +static GlobalMemory deftrig_gcxt = NULL; +static GlobalMemory deftrig_cxt = NULL; /* ---------- * Global data that tells which triggers are actually in * state IMMEDIATE or DEFERRED. * ---------- */ -static bool deftrig_dfl_all_isset = false; -static bool deftrig_dfl_all_isdeferred = false; -static List *deftrig_dfl_trigstates = NIL; +static bool deftrig_dfl_all_isset = false; +static bool deftrig_dfl_all_isdeferred = false; +static List *deftrig_dfl_trigstates = NIL; -static bool deftrig_all_isset; -static bool deftrig_all_isdeferred; -static List *deftrig_trigstates; +static bool deftrig_all_isset; +static bool deftrig_all_isdeferred; +static List *deftrig_trigstates; /* ---------- * The list of events during the entire transaction. * * XXX This must finally be held in a file because of the huge - * number of events that could occur in the real world. + * number of events that could occur in the real world. * ---------- */ -static int deftrig_n_events; -static List *deftrig_events; +static int deftrig_n_events; +static List *deftrig_events; /* ---------- @@ -1051,9 +1054,9 @@ static List *deftrig_events; static bool deferredTriggerCheckState(Oid tgoid, int32 itemstate) { - MemoryContext oldcxt; - List *sl; - DeferredTriggerStatus trigstate; + MemoryContext oldcxt; + List *sl; + DeferredTriggerStatus trigstate; /* ---------- * Not deferrable triggers (i.e. normal AFTER ROW triggers @@ -1068,7 +1071,7 @@ deferredTriggerCheckState(Oid tgoid, int32 itemstate) * Lookup if we know an individual state for this trigger * ---------- */ - foreach (sl, deftrig_trigstates) + foreach(sl, deftrig_trigstates) { trigstate = (DeferredTriggerStatus) lfirst(sl); if (trigstate->dts_tgoid == tgoid) @@ -1092,10 +1095,10 @@ deferredTriggerCheckState(Oid tgoid, int32 itemstate) oldcxt = MemoryContextSwitchTo((MemoryContext) deftrig_cxt); trigstate = (DeferredTriggerStatus) - palloc(sizeof(DeferredTriggerStatusData)); - trigstate->dts_tgoid = tgoid; - trigstate->dts_tgisdeferred = - ((itemstate & TRIGGER_DEFERRED_INITDEFERRED) != 0); + palloc(sizeof(DeferredTriggerStatusData)); + trigstate->dts_tgoid = tgoid; + trigstate->dts_tgisdeferred = + ((itemstate & TRIGGER_DEFERRED_INITDEFERRED) != 0); deftrig_trigstates = lappend(deftrig_trigstates, trigstate); MemoryContextSwitchTo(oldcxt); @@ -1130,8 +1133,8 @@ deferredTriggerAddEvent(DeferredTriggerEvent event) static DeferredTriggerEvent deferredTriggerGetPreviousEvent(Oid relid, ItemPointer ctid) { - DeferredTriggerEvent previous; - int n; + DeferredTriggerEvent previous; + int n; for (n = deftrig_n_events - 1; n >= 0; n--) { @@ -1143,15 +1146,15 @@ deferredTriggerGetPreviousEvent(Oid relid, ItemPointer ctid) continue; if (ItemPointerGetBlockNumber(ctid) == - ItemPointerGetBlockNumber(&(previous->dte_newctid)) && - ItemPointerGetOffsetNumber(ctid) == - ItemPointerGetOffsetNumber(&(previous->dte_newctid))) + ItemPointerGetBlockNumber(&(previous->dte_newctid)) && + ItemPointerGetOffsetNumber(ctid) == + ItemPointerGetOffsetNumber(&(previous->dte_newctid))) return previous; } elog(ERROR, - "deferredTriggerGetPreviousEvent(): event for tuple %s not found", - tidout(ctid)); + "deferredTriggerGetPreviousEvent(): event for tuple %s not found", + tidout(ctid)); return NULL; } @@ -1166,13 +1169,13 @@ deferredTriggerGetPreviousEvent(Oid relid, ItemPointer ctid) static void deferredTriggerExecute(DeferredTriggerEvent event, int itemno) { - Relation rel; - TriggerData SaveTriggerData; - HeapTupleData oldtuple; - HeapTupleData newtuple; - HeapTuple rettuple; - Buffer oldbuffer; - Buffer newbuffer; + Relation rel; + TriggerData SaveTriggerData; + HeapTupleData oldtuple; + HeapTupleData newtuple; + HeapTuple rettuple; + Buffer oldbuffer; + Buffer newbuffer; /* ---------- * Open the heap and fetch the required OLD and NEW tuples. @@ -1200,31 +1203,31 @@ deferredTriggerExecute(DeferredTriggerEvent event, int itemno) * Setup the trigger information * ---------- */ - SaveTriggerData.tg_event = (event->dte_event & TRIGGER_EVENT_OPMASK) | - TRIGGER_EVENT_ROW; + SaveTriggerData.tg_event = (event->dte_event & TRIGGER_EVENT_OPMASK) | + TRIGGER_EVENT_ROW; SaveTriggerData.tg_relation = rel; switch (event->dte_event & TRIGGER_EVENT_OPMASK) { case TRIGGER_EVENT_INSERT: SaveTriggerData.tg_trigtuple = &newtuple; - SaveTriggerData.tg_newtuple = NULL; - SaveTriggerData.tg_trigger = - rel->trigdesc->tg_after_row[TRIGGER_EVENT_INSERT][itemno]; + SaveTriggerData.tg_newtuple = NULL; + SaveTriggerData.tg_trigger = + rel->trigdesc->tg_after_row[TRIGGER_EVENT_INSERT][itemno]; break; case TRIGGER_EVENT_UPDATE: SaveTriggerData.tg_trigtuple = &oldtuple; - SaveTriggerData.tg_newtuple = &newtuple; - SaveTriggerData.tg_trigger = - rel->trigdesc->tg_after_row[TRIGGER_EVENT_UPDATE][itemno]; + SaveTriggerData.tg_newtuple = &newtuple; + SaveTriggerData.tg_trigger = + rel->trigdesc->tg_after_row[TRIGGER_EVENT_UPDATE][itemno]; break; case TRIGGER_EVENT_DELETE: SaveTriggerData.tg_trigtuple = &oldtuple; - SaveTriggerData.tg_newtuple = NULL; - SaveTriggerData.tg_trigger = - rel->trigdesc->tg_after_row[TRIGGER_EVENT_DELETE][itemno]; + SaveTriggerData.tg_newtuple = NULL; + SaveTriggerData.tg_trigger = + rel->trigdesc->tg_after_row[TRIGGER_EVENT_DELETE][itemno]; break; } @@ -1271,11 +1274,11 @@ deferredTriggerExecute(DeferredTriggerEvent event, int itemno) static void deferredTriggerInvokeEvents(bool immediate_only) { - List *el; - DeferredTriggerEvent event; - int still_deferred_ones; - int eventno = -1; - int i; + List *el; + DeferredTriggerEvent event; + int still_deferred_ones; + int eventno = -1; + int i; /* ---------- * For now we process all events - to speedup transaction blocks @@ -1286,7 +1289,7 @@ deferredTriggerInvokeEvents(bool immediate_only) * SET CONSTRAINTS ... command finishes and calls EndQuery. * ---------- */ - foreach (el, deftrig_events) + foreach(el, deftrig_events) { eventno++; @@ -1315,8 +1318,8 @@ deferredTriggerInvokeEvents(bool immediate_only) * ---------- */ if (immediate_only && deferredTriggerCheckState( - event->dte_item[i].dti_tgoid, - event->dte_item[i].dti_state)) + event->dte_item[i].dti_tgoid, + event->dte_item[i].dti_state)) { still_deferred_ones = true; continue; @@ -1367,34 +1370,34 @@ DeferredTriggerInit(void) void DeferredTriggerBeginXact(void) { - MemoryContext oldcxt; - List *l; - DeferredTriggerStatus dflstat; - DeferredTriggerStatus stat; + MemoryContext oldcxt; + List *l; + DeferredTriggerStatus dflstat; + DeferredTriggerStatus stat; if (deftrig_cxt != NULL) elog(FATAL, - "DeferredTriggerBeginXact() called while inside transaction"); + "DeferredTriggerBeginXact() called while inside transaction"); /* ---------- * Create the per transaction memory context and copy all states * from the per session context to here. * ---------- */ - deftrig_cxt = CreateGlobalMemory("DeferredTriggerXact"); - oldcxt = MemoryContextSwitchTo((MemoryContext)deftrig_cxt); + deftrig_cxt = CreateGlobalMemory("DeferredTriggerXact"); + oldcxt = MemoryContextSwitchTo((MemoryContext) deftrig_cxt); - deftrig_all_isset = deftrig_dfl_all_isset; - deftrig_all_isdeferred = deftrig_dfl_all_isdeferred; + deftrig_all_isset = deftrig_dfl_all_isset; + deftrig_all_isdeferred = deftrig_dfl_all_isdeferred; - deftrig_trigstates = NIL; - foreach (l, deftrig_dfl_trigstates) + deftrig_trigstates = NIL; + foreach(l, deftrig_dfl_trigstates) { dflstat = (DeferredTriggerStatus) lfirst(l); - stat = (DeferredTriggerStatus) - palloc(sizeof(DeferredTriggerStatusData)); + stat = (DeferredTriggerStatus) + palloc(sizeof(DeferredTriggerStatusData)); - stat->dts_tgoid = dflstat->dts_tgoid; + stat->dts_tgoid = dflstat->dts_tgoid; stat->dts_tgisdeferred = dflstat->dts_tgisdeferred; deftrig_trigstates = lappend(deftrig_trigstates, stat); @@ -1402,8 +1405,8 @@ DeferredTriggerBeginXact(void) MemoryContextSwitchTo(oldcxt); - deftrig_n_events = 0; - deftrig_events = NIL; + deftrig_n_events = 0; + deftrig_events = NIL; } @@ -1484,22 +1487,23 @@ DeferredTriggerAbortXact(void) void DeferredTriggerSetState(ConstraintsSetStmt *stmt) { - Relation tgrel; - Relation irel = (Relation) NULL; - List *l; - List *ls; - List *lnext; - List *loid = NIL; - MemoryContext oldcxt; - bool found; - DeferredTriggerStatus state; - bool hasindex; + Relation tgrel; + Relation irel = (Relation) NULL; + List *l; + List *ls; + List *lnext; + List *loid = NIL; + MemoryContext oldcxt; + bool found; + DeferredTriggerStatus state; + bool hasindex; /* ---------- * Handle SET CONSTRAINTS ALL ... * ---------- */ - if (stmt->constraints == NIL) { + if (stmt->constraints == NIL) + { if (!IsTransactionBlock()) { /* ---------- @@ -1527,13 +1531,15 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt) * Set the session ALL state to known. * ---------- */ - deftrig_dfl_all_isset = true; + deftrig_dfl_all_isset = true; deftrig_dfl_all_isdeferred = stmt->deferred; MemoryContextSwitchTo(oldcxt); return; - } else { + } + else + { /* ---------- * ... inside of a transaction block * ---------- @@ -1559,7 +1565,7 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt) * Set the per transaction ALL state to known. * ---------- */ - deftrig_all_isset = true; + deftrig_all_isset = true; deftrig_all_isdeferred = stmt->deferred; MemoryContextSwitchTo(oldcxt); @@ -1578,23 +1584,23 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt) if (hasindex) irel = index_openr(TriggerConstrNameIndex); - foreach (l, stmt->constraints) + foreach(l, stmt->constraints) { - ScanKeyData skey; - HeapTupleData tuple; - IndexScanDesc sd = (IndexScanDesc) NULL; - HeapScanDesc tgscan = (HeapScanDesc) NULL; - HeapTuple htup; - RetrieveIndexResult indexRes; - Buffer buffer; - Form_pg_trigger pg_trigger; - Oid constr_oid; + ScanKeyData skey; + HeapTupleData tuple; + IndexScanDesc sd = (IndexScanDesc) NULL; + HeapScanDesc tgscan = (HeapScanDesc) NULL; + HeapTuple htup; + RetrieveIndexResult indexRes; + Buffer buffer; + Form_pg_trigger pg_trigger; + Oid constr_oid; /* ---------- * Check that only named constraints are set explicitly * ---------- */ - if (strcmp((char *)lfirst(l), "") == 0) + if (strcmp((char *) lfirst(l), "") == 0) elog(ERROR, "unnamed constraints cannot be set explicitly"); /* ---------- @@ -1605,7 +1611,7 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt) (bits16) 0x0, (AttrNumber) 1, (RegProcedure) F_NAMEEQ, - PointerGetDatum((char *)lfirst(l))); + PointerGetDatum((char *) lfirst(l))); if (hasindex) sd = index_beginscan(irel, false, 1, &skey); @@ -1629,9 +1635,7 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt) heap_fetch(tgrel, SnapshotNow, &tuple, &buffer); pfree(indexRes); if (!tuple.t_data) - { continue; - } htup = &tuple; } else @@ -1649,13 +1653,13 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt) */ pg_trigger = (Form_pg_trigger) GETSTRUCT(htup); if (stmt->deferred && !pg_trigger->tgdeferrable && - pg_trigger->tgfoid != F_RI_FKEY_RESTRICT_UPD && - pg_trigger->tgfoid != F_RI_FKEY_RESTRICT_DEL) + pg_trigger->tgfoid != F_RI_FKEY_RESTRICT_UPD && + pg_trigger->tgfoid != F_RI_FKEY_RESTRICT_DEL) elog(ERROR, "Constraint '%s' is not deferrable", - (char *)lfirst(l)); + (char *) lfirst(l)); constr_oid = htup->t_data->t_oid; - loid = lappend(loid, (Node *)constr_oid); + loid = lappend(loid, (Node *) constr_oid); found = true; if (hasindex) @@ -1667,11 +1671,11 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt) * ---------- */ if (!found) - elog(ERROR, "Constraint '%s' does not exist", (char *)lfirst(l)); + elog(ERROR, "Constraint '%s' does not exist", (char *) lfirst(l)); if (hasindex) index_endscan(sd); - else + else heap_endscan(tgscan); } if (hasindex) @@ -1688,10 +1692,10 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt) */ oldcxt = MemoryContextSwitchTo((MemoryContext) deftrig_gcxt); - foreach (l, loid) + foreach(l, loid) { found = false; - foreach (ls, deftrig_dfl_trigstates) + foreach(ls, deftrig_dfl_trigstates) { state = (DeferredTriggerStatus) lfirst(ls); if (state->dts_tgoid == (Oid) lfirst(l)) @@ -1704,19 +1708,21 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt) if (!found) { state = (DeferredTriggerStatus) - palloc(sizeof(DeferredTriggerStatusData)); - state->dts_tgoid = (Oid) lfirst(l); + palloc(sizeof(DeferredTriggerStatusData)); + state->dts_tgoid = (Oid) lfirst(l); state->dts_tgisdeferred = stmt->deferred; deftrig_dfl_trigstates = - lappend(deftrig_dfl_trigstates, state); + lappend(deftrig_dfl_trigstates, state); } } MemoryContextSwitchTo(oldcxt); return; - } else { + } + else + { /* ---------- * Inside of a transaction block set the trigger * states of individual triggers on transaction level. @@ -1724,10 +1730,10 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt) */ oldcxt = MemoryContextSwitchTo((MemoryContext) deftrig_cxt); - foreach (l, loid) + foreach(l, loid) { found = false; - foreach (ls, deftrig_trigstates) + foreach(ls, deftrig_trigstates) { state = (DeferredTriggerStatus) lfirst(ls); if (state->dts_tgoid == (Oid) lfirst(l)) @@ -1740,12 +1746,12 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt) if (!found) { state = (DeferredTriggerStatus) - palloc(sizeof(DeferredTriggerStatusData)); - state->dts_tgoid = (Oid) lfirst(l); + palloc(sizeof(DeferredTriggerStatusData)); + state->dts_tgoid = (Oid) lfirst(l); state->dts_tgisdeferred = stmt->deferred; deftrig_trigstates = - lappend(deftrig_trigstates, state); + lappend(deftrig_trigstates, state); } } @@ -1764,33 +1770,33 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt) */ void DeferredTriggerSaveEvent(Relation rel, int event, - HeapTuple oldtup, HeapTuple newtup) + HeapTuple oldtup, HeapTuple newtup) { - MemoryContext oldcxt; - DeferredTriggerEvent new_event; - DeferredTriggerEvent prev_event; - int new_size; - int i; - int ntriggers; - Trigger **triggers; - ItemPointerData oldctid; - ItemPointerData newctid; - TriggerData SaveTriggerData; + MemoryContext oldcxt; + DeferredTriggerEvent new_event; + DeferredTriggerEvent prev_event; + int new_size; + int i; + int ntriggers; + Trigger **triggers; + ItemPointerData oldctid; + ItemPointerData newctid; + TriggerData SaveTriggerData; if (deftrig_cxt == NULL) elog(ERROR, - "DeferredTriggerSaveEvent() called outside of transaction"); + "DeferredTriggerSaveEvent() called outside of transaction"); /* ---------- * Check if we're interested in this row at all * ---------- */ if (rel->trigdesc->n_after_row[TRIGGER_EVENT_INSERT] == 0 && - rel->trigdesc->n_after_row[TRIGGER_EVENT_UPDATE] == 0 && - rel->trigdesc->n_after_row[TRIGGER_EVENT_DELETE] == 0 && - rel->trigdesc->n_before_row[TRIGGER_EVENT_INSERT] == 0 && - rel->trigdesc->n_before_row[TRIGGER_EVENT_UPDATE] == 0 && - rel->trigdesc->n_before_row[TRIGGER_EVENT_DELETE] == 0) + rel->trigdesc->n_after_row[TRIGGER_EVENT_UPDATE] == 0 && + rel->trigdesc->n_after_row[TRIGGER_EVENT_DELETE] == 0 && + rel->trigdesc->n_before_row[TRIGGER_EVENT_INSERT] == 0 && + rel->trigdesc->n_before_row[TRIGGER_EVENT_UPDATE] == 0 && + rel->trigdesc->n_before_row[TRIGGER_EVENT_DELETE] == 0) return; /* ---------- @@ -1813,14 +1819,14 @@ DeferredTriggerSaveEvent(Relation rel, int event, oldcxt = MemoryContextSwitchTo((MemoryContext) deftrig_cxt); ntriggers = rel->trigdesc->n_after_row[event]; - triggers = rel->trigdesc->tg_after_row[event]; + triggers = rel->trigdesc->tg_after_row[event]; - new_size = sizeof(DeferredTriggerEventData) + - ntriggers * sizeof(DeferredTriggerEventItem); + new_size = sizeof(DeferredTriggerEventData) + + ntriggers * sizeof(DeferredTriggerEventItem); new_event = (DeferredTriggerEvent) palloc(new_size); - new_event->dte_event = event & TRIGGER_EVENT_OPMASK; - new_event->dte_relid = rel->rd_id; + new_event->dte_event = event & TRIGGER_EVENT_OPMASK; + new_event->dte_relid = rel->rd_id; ItemPointerCopy(&oldctid, &(new_event->dte_oldctid)); ItemPointerCopy(&newctid, &(new_event->dte_newctid)); new_event->dte_n_items = ntriggers; @@ -1830,11 +1836,11 @@ DeferredTriggerSaveEvent(Relation rel, int event, new_event->dte_item[i].dti_tgoid = triggers[i]->tgoid; new_event->dte_item[i].dti_state = ((triggers[i]->tgdeferrable) ? - TRIGGER_DEFERRED_DEFERRABLE : 0) | + TRIGGER_DEFERRED_DEFERRABLE : 0) | ((triggers[i]->tginitdeferred) ? - TRIGGER_DEFERRED_INITDEFERRED : 0) | + TRIGGER_DEFERRED_INITDEFERRED : 0) | ((rel->trigdesc->n_before_row[event] > 0) ? - TRIGGER_DEFERRED_HAS_BEFORE : 0); + TRIGGER_DEFERRED_HAS_BEFORE : 0); } MemoryContextSwitchTo(oldcxt); @@ -1864,8 +1870,8 @@ DeferredTriggerSaveEvent(Relation rel, int event, */ for (i = 0; i < ntriggers; i++) { - bool is_ri_trigger; - bool key_unchanged; + bool is_ri_trigger; + bool key_unchanged; /* ---------- * We are interested in RI_FKEY triggers only. @@ -1888,11 +1894,11 @@ DeferredTriggerSaveEvent(Relation rel, int event, if (!is_ri_trigger) continue; - SaveTriggerData.tg_event = TRIGGER_EVENT_UPDATE; - SaveTriggerData.tg_relation = rel; + SaveTriggerData.tg_event = TRIGGER_EVENT_UPDATE; + SaveTriggerData.tg_relation = rel; SaveTriggerData.tg_trigtuple = oldtup; - SaveTriggerData.tg_newtuple = newtup; - SaveTriggerData.tg_trigger = triggers[i]; + SaveTriggerData.tg_newtuple = newtup; + SaveTriggerData.tg_trigger = triggers[i]; CurrentTriggerData = &SaveTriggerData; key_unchanged = RI_FKey_keyequal_upd(); @@ -1911,7 +1917,7 @@ DeferredTriggerSaveEvent(Relation rel, int event, if (prev_event) { if (prev_event->dte_event & - TRIGGER_DEFERRED_ROW_INSERTED) + TRIGGER_DEFERRED_ROW_INSERTED) { /* ---------- * This is a row inserted during our transaction. @@ -1919,11 +1925,11 @@ DeferredTriggerSaveEvent(Relation rel, int event, * ---------- */ new_event->dte_event |= - TRIGGER_DEFERRED_ROW_INSERTED; + TRIGGER_DEFERRED_ROW_INSERTED; new_event->dte_event |= - TRIGGER_DEFERRED_KEY_CHANGED; + TRIGGER_DEFERRED_KEY_CHANGED; new_event->dte_item[i].dti_state |= - TRIGGER_DEFERRED_KEY_CHANGED; + TRIGGER_DEFERRED_KEY_CHANGED; } else { @@ -1934,12 +1940,12 @@ DeferredTriggerSaveEvent(Relation rel, int event, * ---------- */ if (prev_event->dte_item[i].dti_state & - TRIGGER_DEFERRED_KEY_CHANGED) + TRIGGER_DEFERRED_KEY_CHANGED) { new_event->dte_item[i].dti_state |= - TRIGGER_DEFERRED_KEY_CHANGED; + TRIGGER_DEFERRED_KEY_CHANGED; new_event->dte_event |= - TRIGGER_DEFERRED_KEY_CHANGED; + TRIGGER_DEFERRED_KEY_CHANGED; } } } @@ -1954,16 +1960,16 @@ DeferredTriggerSaveEvent(Relation rel, int event, if (prev_event) { if (prev_event->dte_event & - TRIGGER_DEFERRED_ROW_INSERTED) + TRIGGER_DEFERRED_ROW_INSERTED) elog(ERROR, "triggered data change violation " - "on relation \"%s\"", - nameout(&(rel->rd_rel->relname))); + "on relation \"%s\"", + nameout(&(rel->rd_rel->relname))); if (prev_event->dte_item[i].dti_state & - TRIGGER_DEFERRED_KEY_CHANGED) + TRIGGER_DEFERRED_KEY_CHANGED) elog(ERROR, "triggered data change violation " - "on relation \"%s\"", - nameout(&(rel->rd_rel->relname))); + "on relation \"%s\"", + nameout(&(rel->rd_rel->relname))); } /* ---------- @@ -1972,7 +1978,7 @@ DeferredTriggerSaveEvent(Relation rel, int event, * ---------- */ new_event->dte_item[i].dti_state |= - TRIGGER_DEFERRED_KEY_CHANGED; + TRIGGER_DEFERRED_KEY_CHANGED; new_event->dte_event |= TRIGGER_DEFERRED_KEY_CHANGED; } } @@ -1996,8 +2002,8 @@ DeferredTriggerSaveEvent(Relation rel, int event, prev_event = deferredTriggerGetPreviousEvent(rel->rd_id, &oldctid); if (prev_event->dte_event & TRIGGER_DEFERRED_KEY_CHANGED) elog(ERROR, "triggered data change violation " - "on relation \"%s\"", - nameout(&(rel->rd_rel->relname))); + "on relation \"%s\"", + nameout(&(rel->rd_rel->relname))); break; } @@ -2012,5 +2018,3 @@ DeferredTriggerSaveEvent(Relation rel, int event, return; } - - diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c index 63676e14e48..fe24e15b1fd 100644 --- a/src/backend/commands/user.c +++ b/src/backend/commands/user.c @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: user.c,v 1.51 2000/03/15 07:02:56 tgl Exp $ + * $Id: user.c,v 1.52 2000/04/12 17:14:59 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -55,11 +55,11 @@ write_password_file(Relation rel) char *filename, *tempname; int bufsize; - FILE *fp; - mode_t oumask; - HeapScanDesc scan; - HeapTuple tuple; - TupleDesc dsc = RelationGetDescr(rel); + FILE *fp; + mode_t oumask; + HeapScanDesc scan; + HeapTuple tuple; + TupleDesc dsc = RelationGetDescr(rel); /* * Create a temporary filename to be renamed later. This prevents the @@ -71,74 +71,85 @@ write_password_file(Relation rel) tempname = (char *) palloc(bufsize); snprintf(tempname, bufsize, "%s.%d", filename, MyProcPid); - oumask = umask((mode_t) 077); - fp = AllocateFile(tempname, "w"); - umask(oumask); - if (fp == NULL) - elog(ERROR, "%s: %s", tempname, strerror(errno)); - - /* read table */ - scan = heap_beginscan(rel, false, SnapshotSelf, 0, NULL); - while (HeapTupleIsValid(tuple = heap_getnext(scan, 0))) - { - Datum datum_n, datum_p, datum_v; - bool null_n, null_p, null_v; + oumask = umask((mode_t) 077); + fp = AllocateFile(tempname, "w"); + umask(oumask); + if (fp == NULL) + elog(ERROR, "%s: %s", tempname, strerror(errno)); + + /* read table */ + scan = heap_beginscan(rel, false, SnapshotSelf, 0, NULL); + while (HeapTupleIsValid(tuple = heap_getnext(scan, 0))) + { + Datum datum_n, + datum_p, + datum_v; + bool null_n, + null_p, + null_v; datum_n = heap_getattr(tuple, Anum_pg_shadow_usename, dsc, &null_n); - if (null_n) - continue; /* don't allow empty users */ + if (null_n) + continue; /* don't allow empty users */ datum_p = heap_getattr(tuple, Anum_pg_shadow_passwd, dsc, &null_p); - /* It could be argued that people having a null password - shouldn't be allowed to connect, because they need - to have a password set up first. If you think assuming - an empty password in that case is better, erase the following line. */ - if (null_p) - continue; + + /* + * It could be argued that people having a null password shouldn't + * be allowed to connect, because they need to have a password set + * up first. If you think assuming an empty password in that case + * is better, erase the following line. + */ + if (null_p) + continue; datum_v = heap_getattr(tuple, Anum_pg_shadow_valuntil, dsc, &null_v); - /* These fake entries are not really necessary. To remove them, the parser - in backend/libpq/crypt.c would need to be adjusted. Initdb might also - need adjustments. */ - fprintf(fp, - "%s" - CRYPT_PWD_FILE_SEPSTR - "0" - CRYPT_PWD_FILE_SEPSTR - "x" - CRYPT_PWD_FILE_SEPSTR - "x" - CRYPT_PWD_FILE_SEPSTR - "x" - CRYPT_PWD_FILE_SEPSTR - "x" - CRYPT_PWD_FILE_SEPSTR - "%s" - CRYPT_PWD_FILE_SEPSTR - "%s\n", - nameout(DatumGetName(datum_n)), - null_p ? "" : textout((text*)datum_p), - null_v ? "\\N" : nabstimeout((AbsoluteTime)datum_v) /* this is how the parser wants it */ - ); - if (ferror(fp)) - elog(ERROR, "%s: %s", tempname, strerror(errno)); - fflush(fp); - } - heap_endscan(scan); - FreeFile(fp); - - /* - * And rename the temp file to its final name, deleting the old pg_pwd. - */ - rename(tempname, filename); - - /* + /* + * These fake entries are not really necessary. To remove them, + * the parser in backend/libpq/crypt.c would need to be adjusted. + * Initdb might also need adjustments. + */ + fprintf(fp, + "%s" + CRYPT_PWD_FILE_SEPSTR + "0" + CRYPT_PWD_FILE_SEPSTR + "x" + CRYPT_PWD_FILE_SEPSTR + "x" + CRYPT_PWD_FILE_SEPSTR + "x" + CRYPT_PWD_FILE_SEPSTR + "x" + CRYPT_PWD_FILE_SEPSTR + "%s" + CRYPT_PWD_FILE_SEPSTR + "%s\n", + nameout(DatumGetName(datum_n)), + null_p ? "" : textout((text *) datum_p), + null_v ? "\\N" : nabstimeout((AbsoluteTime) datum_v) /* this is how the + * parser wants it */ + ); + if (ferror(fp)) + elog(ERROR, "%s: %s", tempname, strerror(errno)); + fflush(fp); + } + heap_endscan(scan); + FreeFile(fp); + + /* + * And rename the temp file to its final name, deleting the old + * pg_pwd. + */ + rename(tempname, filename); + + /* * Create a flag file the postmaster will detect the next time it * tries to authenticate a user. The postmaster will know to reload * the pg_pwd file contents. */ filename = crypt_getpwdreloadfilename(); if (creat(filename, S_IRUSR | S_IWUSR) == -1) - elog(ERROR, "%s: %s", filename, strerror(errno)); + elog(ERROR, "%s: %s", filename, strerror(errno)); pfree((void *) tempname); } @@ -149,16 +160,17 @@ write_password_file(Relation rel) HeapTuple update_pg_pwd(void) { - Relation rel = heap_openr(ShadowRelationName, AccessExclusiveLock); - write_password_file(rel); - heap_close(rel, AccessExclusiveLock); + Relation rel = heap_openr(ShadowRelationName, AccessExclusiveLock); + + write_password_file(rel); + heap_close(rel, AccessExclusiveLock); /* - * This is a trigger, so clean out the information provided by - * the trigger manager. + * This is a trigger, so clean out the information provided by the + * trigger manager. */ CurrentTriggerData = NULL; - return NULL; + return NULL; } @@ -173,36 +185,37 @@ CreateUser(CreateUserStmt *stmt) TupleDesc pg_shadow_dsc; HeapScanDesc scan; HeapTuple tuple; - Datum new_record[Natts_pg_shadow]; - char new_record_nulls[Natts_pg_shadow]; + Datum new_record[Natts_pg_shadow]; + char new_record_nulls[Natts_pg_shadow]; bool user_exists = false, - sysid_exists = false, - havesysid; + sysid_exists = false, + havesysid; int max_id = -1; - List *item; + List *item; - havesysid = stmt->sysid > 0; + havesysid = stmt->sysid > 0; - /* Check some permissions first */ + /* Check some permissions first */ if (stmt->password) CheckPgUserAclNotNull(); - if (!superuser()) - elog(ERROR, "CREATE USER: permission denied"); + if (!superuser()) + elog(ERROR, "CREATE USER: permission denied"); - /* The reason for the following is this: - * If you start a transaction block, create a user, then roll back the - * transaction, the pg_pwd won't get rolled back due to a bug in the - * Unix file system ( :}). Hence this is in the interest of security. - */ + /* + * The reason for the following is this: If you start a transaction + * block, create a user, then roll back the transaction, the pg_pwd + * won't get rolled back due to a bug in the Unix file system ( :}). + * Hence this is in the interest of security. + */ if (IsTransactionBlock()) - elog(ERROR, "CREATE USER: may not be called in a transaction block"); + elog(ERROR, "CREATE USER: may not be called in a transaction block"); /* - * Scan the pg_shadow relation to be certain the user or id doesn't already - * exist. Note we secure exclusive lock, because we also need to be - * sure of what the next usesysid should be, and we need to protect - * our update of the flat password file. + * Scan the pg_shadow relation to be certain the user or id doesn't + * already exist. Note we secure exclusive lock, because we also need + * to be sure of what the next usesysid should be, and we need to + * protect our update of the flat password file. */ pg_shadow_rel = heap_openr(ShadowRelationName, AccessExclusiveLock); pg_shadow_dsc = RelationGetDescr(pg_shadow_rel); @@ -210,103 +223,108 @@ CreateUser(CreateUserStmt *stmt) scan = heap_beginscan(pg_shadow_rel, false, SnapshotNow, 0, NULL); while (!user_exists && !sysid_exists && HeapTupleIsValid(tuple = heap_getnext(scan, 0))) { - Datum datum; - bool null; + Datum datum; + bool null; datum = heap_getattr(tuple, Anum_pg_shadow_usename, pg_shadow_dsc, &null); user_exists = datum && !null && (strcmp((char *) datum, stmt->user) == 0); datum = heap_getattr(tuple, Anum_pg_shadow_usesysid, pg_shadow_dsc, &null); - if (havesysid) /* customized id wanted */ - sysid_exists = datum && !null && ((int)datum == stmt->sysid); - else /* pick 1 + max */ - { - if ((int) datum > max_id) - max_id = (int) datum; - } + if (havesysid) /* customized id wanted */ + sysid_exists = datum && !null && ((int) datum == stmt->sysid); + else +/* pick 1 + max */ + { + if ((int) datum > max_id) + max_id = (int) datum; + } } heap_endscan(scan); if (user_exists || sysid_exists) { heap_close(pg_shadow_rel, AccessExclusiveLock); - if (user_exists) - elog(ERROR, "CREATE USER: user name \"%s\" already exists", stmt->user); - else - elog(ERROR, "CREATE USER: sysid %d is already assigned", stmt->sysid); + if (user_exists) + elog(ERROR, "CREATE USER: user name \"%s\" already exists", stmt->user); + else + elog(ERROR, "CREATE USER: sysid %d is already assigned", stmt->sysid); return; } - /* - * Build a tuple to insert - */ - new_record[Anum_pg_shadow_usename-1] = PointerGetDatum(namein(stmt->user)); /* this truncated properly */ - new_record[Anum_pg_shadow_usesysid-1] = Int32GetDatum(havesysid ? stmt->sysid : max_id + 1); - - AssertState(BoolIsValid(stmt->createdb)); - new_record[Anum_pg_shadow_usecreatedb-1] = (Datum)(stmt->createdb); - new_record[Anum_pg_shadow_usetrace-1] = (Datum)(false); - AssertState(BoolIsValid(stmt->createuser)); - new_record[Anum_pg_shadow_usesuper-1] = (Datum)(stmt->createuser); - /* superuser gets catupd right by default */ - new_record[Anum_pg_shadow_usecatupd-1] = (Datum)(stmt->createuser); - - if (stmt->password) - new_record[Anum_pg_shadow_passwd-1] = PointerGetDatum(textin(stmt->password)); - if (stmt->validUntil) - new_record[Anum_pg_shadow_valuntil-1] = PointerGetDatum(nabstimein(stmt->validUntil)); - - new_record_nulls[Anum_pg_shadow_usename-1] = ' '; - new_record_nulls[Anum_pg_shadow_usesysid-1] = ' '; - - new_record_nulls[Anum_pg_shadow_usecreatedb-1] = ' '; - new_record_nulls[Anum_pg_shadow_usetrace-1] = ' '; - new_record_nulls[Anum_pg_shadow_usesuper-1] = ' '; - new_record_nulls[Anum_pg_shadow_usecatupd-1] = ' '; - - new_record_nulls[Anum_pg_shadow_passwd-1] = stmt->password ? ' ' : 'n'; - new_record_nulls[Anum_pg_shadow_valuntil-1] = stmt->validUntil ? ' ' : 'n'; - - tuple = heap_formtuple(pg_shadow_dsc, new_record, new_record_nulls); - Assert(tuple); - - /* - * Insert a new record in the pg_shadow table - */ - if (heap_insert(pg_shadow_rel, tuple) == InvalidOid) - elog(ERROR, "CREATE USER: heap_insert failed"); - - /* - * Update indexes - */ - if (RelationGetForm(pg_shadow_rel)->relhasindex) { - Relation idescs[Num_pg_shadow_indices]; - - CatalogOpenIndices(Num_pg_shadow_indices, - Name_pg_shadow_indices, idescs); - CatalogIndexInsert(idescs, Num_pg_shadow_indices, pg_shadow_rel, - tuple); - CatalogCloseIndices(Num_pg_shadow_indices, idescs); - } + /* + * Build a tuple to insert + */ + new_record[Anum_pg_shadow_usename - 1] = PointerGetDatum(namein(stmt->user)); /* this truncated + * properly */ + new_record[Anum_pg_shadow_usesysid - 1] = Int32GetDatum(havesysid ? stmt->sysid : max_id + 1); + + AssertState(BoolIsValid(stmt->createdb)); + new_record[Anum_pg_shadow_usecreatedb - 1] = (Datum) (stmt->createdb); + new_record[Anum_pg_shadow_usetrace - 1] = (Datum) (false); + AssertState(BoolIsValid(stmt->createuser)); + new_record[Anum_pg_shadow_usesuper - 1] = (Datum) (stmt->createuser); + /* superuser gets catupd right by default */ + new_record[Anum_pg_shadow_usecatupd - 1] = (Datum) (stmt->createuser); + + if (stmt->password) + new_record[Anum_pg_shadow_passwd - 1] = PointerGetDatum(textin(stmt->password)); + if (stmt->validUntil) + new_record[Anum_pg_shadow_valuntil - 1] = PointerGetDatum(nabstimein(stmt->validUntil)); + + new_record_nulls[Anum_pg_shadow_usename - 1] = ' '; + new_record_nulls[Anum_pg_shadow_usesysid - 1] = ' '; + + new_record_nulls[Anum_pg_shadow_usecreatedb - 1] = ' '; + new_record_nulls[Anum_pg_shadow_usetrace - 1] = ' '; + new_record_nulls[Anum_pg_shadow_usesuper - 1] = ' '; + new_record_nulls[Anum_pg_shadow_usecatupd - 1] = ' '; + + new_record_nulls[Anum_pg_shadow_passwd - 1] = stmt->password ? ' ' : 'n'; + new_record_nulls[Anum_pg_shadow_valuntil - 1] = stmt->validUntil ? ' ' : 'n'; + + tuple = heap_formtuple(pg_shadow_dsc, new_record, new_record_nulls); + Assert(tuple); + + /* + * Insert a new record in the pg_shadow table + */ + if (heap_insert(pg_shadow_rel, tuple) == InvalidOid) + elog(ERROR, "CREATE USER: heap_insert failed"); + + /* + * Update indexes + */ + if (RelationGetForm(pg_shadow_rel)->relhasindex) + { + Relation idescs[Num_pg_shadow_indices]; + + CatalogOpenIndices(Num_pg_shadow_indices, + Name_pg_shadow_indices, idescs); + CatalogIndexInsert(idescs, Num_pg_shadow_indices, pg_shadow_rel, + tuple); + CatalogCloseIndices(Num_pg_shadow_indices, idescs); + } /* * Add the user to the groups specified. We'll just call the below - * AlterGroup for this. + * AlterGroup for this. */ - foreach(item, stmt->groupElts) - { - AlterGroupStmt ags; + foreach(item, stmt->groupElts) + { + AlterGroupStmt ags; - ags.name = strVal(lfirst(item)); /* the group name to add this in */ - ags.action = +1; - ags.listUsers = lcons((void*)makeInteger(havesysid ? stmt->sysid : max_id + 1), NIL); - AlterGroup(&ags, "CREATE USER"); - } + ags.name = strVal(lfirst(item)); /* the group name to add + * this in */ + ags.action = +1; + ags.listUsers = lcons((void *) makeInteger(havesysid ? stmt->sysid : max_id + 1), NIL); + AlterGroup(&ags, "CREATE USER"); + } /* * Write the updated pg_shadow data to the flat password file. */ - write_password_file(pg_shadow_rel); + write_password_file(pg_shadow_rel); + /* * Now we can clean up. */ @@ -321,30 +339,31 @@ CreateUser(CreateUserStmt *stmt) extern void AlterUser(AlterUserStmt *stmt) { - Datum new_record[Natts_pg_shadow]; - char new_record_nulls[Natts_pg_shadow]; + Datum new_record[Natts_pg_shadow]; + char new_record_nulls[Natts_pg_shadow]; Relation pg_shadow_rel; TupleDesc pg_shadow_dsc; - HeapTuple tuple, new_tuple; - bool null; + HeapTuple tuple, + new_tuple; + bool null; if (stmt->password) CheckPgUserAclNotNull(); - /* must be superuser or just want to change your own password */ - if (!superuser() && - !(stmt->createdb==0 && stmt->createuser==0 && !stmt->validUntil - && stmt->password && strcmp(GetPgUserName(), stmt->user)==0)) - elog(ERROR, "ALTER USER: permission denied"); + /* must be superuser or just want to change your own password */ + if (!superuser() && + !(stmt->createdb == 0 && stmt->createuser == 0 && !stmt->validUntil + && stmt->password && strcmp(GetPgUserName(), stmt->user) == 0)) + elog(ERROR, "ALTER USER: permission denied"); - /* see comments in create user */ + /* see comments in create user */ if (IsTransactionBlock()) - elog(ERROR, "ALTER USER: may not be called in a transaction block"); + elog(ERROR, "ALTER USER: may not be called in a transaction block"); /* - * Scan the pg_shadow relation to be certain the user exists. - * Note we secure exclusive lock to protect our update of the - * flat password file. + * Scan the pg_shadow relation to be certain the user exists. Note we + * secure exclusive lock to protect our update of the flat password + * file. */ pg_shadow_rel = heap_openr(ShadowRelationName, AccessExclusiveLock); pg_shadow_dsc = RelationGetDescr(pg_shadow_rel); @@ -358,107 +377,107 @@ AlterUser(AlterUserStmt *stmt) elog(ERROR, "ALTER USER: user \"%s\" does not exist", stmt->user); } - /* - * Build a tuple to update, perusing the information just obtained - */ - new_record[Anum_pg_shadow_usename-1] = PointerGetDatum(namein(stmt->user)); - new_record_nulls[Anum_pg_shadow_usename-1] = ' '; - - /* sysid - leave as is */ - new_record[Anum_pg_shadow_usesysid-1] = heap_getattr(tuple, Anum_pg_shadow_usesysid, pg_shadow_dsc, &null); - new_record_nulls[Anum_pg_shadow_usesysid-1] = null ? 'n' : ' '; - - /* createdb */ - if (stmt->createdb == 0) - { - /* don't change */ - new_record[Anum_pg_shadow_usecreatedb-1] = heap_getattr(tuple, Anum_pg_shadow_usecreatedb, pg_shadow_dsc, &null); - new_record_nulls[Anum_pg_shadow_usecreatedb-1] = null ? 'n' : ' '; - } - else - { - new_record[Anum_pg_shadow_usecreatedb-1] = (Datum)(stmt->createdb > 0 ? true : false); - new_record_nulls[Anum_pg_shadow_usecreatedb-1] = ' '; - } - - /* trace - leave as is */ - new_record[Anum_pg_shadow_usetrace-1] = heap_getattr(tuple, Anum_pg_shadow_usetrace, pg_shadow_dsc, &null); - new_record_nulls[Anum_pg_shadow_usetrace-1] = null ? 'n' : ' '; - - /* createuser (superuser) */ - if (stmt->createuser == 0) - { - /* don't change */ - new_record[Anum_pg_shadow_usesuper-1] = heap_getattr(tuple, Anum_pg_shadow_usesuper, pg_shadow_dsc, &null); - new_record_nulls[Anum_pg_shadow_usesuper-1] = null ? 'n' : ' '; - } - else - { - new_record[Anum_pg_shadow_usesuper-1] = (Datum)(stmt->createuser > 0 ? true : false); - new_record_nulls[Anum_pg_shadow_usesuper-1] = ' '; - } - - /* catupd - set to false if someone's superuser priv is being yanked */ - if (stmt->createuser < 0) - { - new_record[Anum_pg_shadow_usecatupd-1] = (Datum)(false); - new_record_nulls[Anum_pg_shadow_usecatupd-1] = ' '; - } - else - { - /* leave alone */ - new_record[Anum_pg_shadow_usecatupd-1] = heap_getattr(tuple, Anum_pg_shadow_usecatupd, pg_shadow_dsc, &null); - new_record_nulls[Anum_pg_shadow_usecatupd-1] = null ? 'n' : ' '; - } - - /* password */ - if (stmt->password) - { - new_record[Anum_pg_shadow_passwd-1] = PointerGetDatum(textin(stmt->password)); - new_record_nulls[Anum_pg_shadow_passwd-1] = ' '; - } - else - { - /* leave as is */ - new_record[Anum_pg_shadow_passwd-1] = heap_getattr(tuple, Anum_pg_shadow_passwd, pg_shadow_dsc, &null); - new_record_nulls[Anum_pg_shadow_passwd-1] = null ? 'n' : ' '; - } - - /* valid until */ - if (stmt->validUntil) - { - new_record[Anum_pg_shadow_valuntil-1] = PointerGetDatum(nabstimein(stmt->validUntil)); - new_record_nulls[Anum_pg_shadow_valuntil-1] = ' '; - } - else - { - /* leave as is */ - new_record[Anum_pg_shadow_valuntil-1] = heap_getattr(tuple, Anum_pg_shadow_valuntil, pg_shadow_dsc, &null); - new_record_nulls[Anum_pg_shadow_valuntil-1] = null ? 'n' : ' '; - } - - new_tuple = heap_formtuple(pg_shadow_dsc, new_record, new_record_nulls); - Assert(new_tuple); - /* XXX check return value of this? */ - heap_update(pg_shadow_rel, &tuple->t_self, new_tuple, NULL); - - - /* Update indexes */ - if (RelationGetForm(pg_shadow_rel)->relhasindex) - { - Relation idescs[Num_pg_shadow_indices]; - - CatalogOpenIndices(Num_pg_shadow_indices, - Name_pg_shadow_indices, idescs); - CatalogIndexInsert(idescs, Num_pg_shadow_indices, pg_shadow_rel, - tuple); - CatalogCloseIndices(Num_pg_shadow_indices, idescs); - } + /* + * Build a tuple to update, perusing the information just obtained + */ + new_record[Anum_pg_shadow_usename - 1] = PointerGetDatum(namein(stmt->user)); + new_record_nulls[Anum_pg_shadow_usename - 1] = ' '; + + /* sysid - leave as is */ + new_record[Anum_pg_shadow_usesysid - 1] = heap_getattr(tuple, Anum_pg_shadow_usesysid, pg_shadow_dsc, &null); + new_record_nulls[Anum_pg_shadow_usesysid - 1] = null ? 'n' : ' '; + + /* createdb */ + if (stmt->createdb == 0) + { + /* don't change */ + new_record[Anum_pg_shadow_usecreatedb - 1] = heap_getattr(tuple, Anum_pg_shadow_usecreatedb, pg_shadow_dsc, &null); + new_record_nulls[Anum_pg_shadow_usecreatedb - 1] = null ? 'n' : ' '; + } + else + { + new_record[Anum_pg_shadow_usecreatedb - 1] = (Datum) (stmt->createdb > 0 ? true : false); + new_record_nulls[Anum_pg_shadow_usecreatedb - 1] = ' '; + } + + /* trace - leave as is */ + new_record[Anum_pg_shadow_usetrace - 1] = heap_getattr(tuple, Anum_pg_shadow_usetrace, pg_shadow_dsc, &null); + new_record_nulls[Anum_pg_shadow_usetrace - 1] = null ? 'n' : ' '; + + /* createuser (superuser) */ + if (stmt->createuser == 0) + { + /* don't change */ + new_record[Anum_pg_shadow_usesuper - 1] = heap_getattr(tuple, Anum_pg_shadow_usesuper, pg_shadow_dsc, &null); + new_record_nulls[Anum_pg_shadow_usesuper - 1] = null ? 'n' : ' '; + } + else + { + new_record[Anum_pg_shadow_usesuper - 1] = (Datum) (stmt->createuser > 0 ? true : false); + new_record_nulls[Anum_pg_shadow_usesuper - 1] = ' '; + } + + /* catupd - set to false if someone's superuser priv is being yanked */ + if (stmt->createuser < 0) + { + new_record[Anum_pg_shadow_usecatupd - 1] = (Datum) (false); + new_record_nulls[Anum_pg_shadow_usecatupd - 1] = ' '; + } + else + { + /* leave alone */ + new_record[Anum_pg_shadow_usecatupd - 1] = heap_getattr(tuple, Anum_pg_shadow_usecatupd, pg_shadow_dsc, &null); + new_record_nulls[Anum_pg_shadow_usecatupd - 1] = null ? 'n' : ' '; + } + + /* password */ + if (stmt->password) + { + new_record[Anum_pg_shadow_passwd - 1] = PointerGetDatum(textin(stmt->password)); + new_record_nulls[Anum_pg_shadow_passwd - 1] = ' '; + } + else + { + /* leave as is */ + new_record[Anum_pg_shadow_passwd - 1] = heap_getattr(tuple, Anum_pg_shadow_passwd, pg_shadow_dsc, &null); + new_record_nulls[Anum_pg_shadow_passwd - 1] = null ? 'n' : ' '; + } + + /* valid until */ + if (stmt->validUntil) + { + new_record[Anum_pg_shadow_valuntil - 1] = PointerGetDatum(nabstimein(stmt->validUntil)); + new_record_nulls[Anum_pg_shadow_valuntil - 1] = ' '; + } + else + { + /* leave as is */ + new_record[Anum_pg_shadow_valuntil - 1] = heap_getattr(tuple, Anum_pg_shadow_valuntil, pg_shadow_dsc, &null); + new_record_nulls[Anum_pg_shadow_valuntil - 1] = null ? 'n' : ' '; + } + + new_tuple = heap_formtuple(pg_shadow_dsc, new_record, new_record_nulls); + Assert(new_tuple); + /* XXX check return value of this? */ + heap_update(pg_shadow_rel, &tuple->t_self, new_tuple, NULL); + + + /* Update indexes */ + if (RelationGetForm(pg_shadow_rel)->relhasindex) + { + Relation idescs[Num_pg_shadow_indices]; + + CatalogOpenIndices(Num_pg_shadow_indices, + Name_pg_shadow_indices, idescs); + CatalogIndexInsert(idescs, Num_pg_shadow_indices, pg_shadow_rel, + tuple); + CatalogCloseIndices(Num_pg_shadow_indices, idescs); + } /* * Write the updated pg_shadow data to the flat password file. */ - write_password_file(pg_shadow_rel); + write_password_file(pg_shadow_rel); /* * Now we can clean up. @@ -477,13 +496,13 @@ DropUser(DropUserStmt *stmt) { Relation pg_shadow_rel; TupleDesc pg_shadow_dsc; - List *item; + List *item; - if (!superuser()) - elog(ERROR, "DROP USER: permission denied"); + if (!superuser()) + elog(ERROR, "DROP USER: permission denied"); if (IsTransactionBlock()) - elog(ERROR, "DROP USER: may not be called in a transaction block"); + elog(ERROR, "DROP USER: may not be called in a transaction block"); /* * Scan the pg_shadow relation to find the usesysid of the user to be @@ -493,103 +512,105 @@ DropUser(DropUserStmt *stmt) pg_shadow_rel = heap_openr(ShadowRelationName, AccessExclusiveLock); pg_shadow_dsc = RelationGetDescr(pg_shadow_rel); - foreach(item, stmt->users) - { - HeapTuple tuple, - tmp_tuple; - Relation pg_rel; - TupleDesc pg_dsc; - ScanKeyData scankey; - HeapScanDesc scan; - Datum datum; - bool null; - int32 usesysid; - const char *user = strVal(lfirst(item)); - - tuple = SearchSysCacheTuple(SHADOWNAME, - PointerGetDatum(user), - 0, 0, 0); - if (!HeapTupleIsValid(tuple)) - { - heap_close(pg_shadow_rel, AccessExclusiveLock); - elog(ERROR, "DROP USER: user \"%s\" does not exist%s", user, - (length(stmt->users) > 1) ? " (no users removed)" : ""); - } - - usesysid = DatumGetInt32(heap_getattr(tuple, Anum_pg_shadow_usesysid, pg_shadow_dsc, &null)); - - /*------------------- - * Check if user still owns a database. If so, error out. - * - * (It used to be that this function would drop the database automatically. - * This is not only very dangerous for people that don't read the manual, - * it doesn't seem to be the behaviour one would expect either.) - * -- petere 2000/01/14) - *-------------------*/ - pg_rel = heap_openr(DatabaseRelationName, AccessExclusiveLock); - pg_dsc = RelationGetDescr(pg_rel); - - ScanKeyEntryInitialize(&scankey, 0x0, Anum_pg_database_datdba, F_INT4EQ, - Int32GetDatum(usesysid)); - - scan = heap_beginscan(pg_rel, false, SnapshotNow, 1, &scankey); - - if (HeapTupleIsValid(tmp_tuple = heap_getnext(scan, 0))) - { - datum = heap_getattr(tmp_tuple, Anum_pg_database_datname, pg_dsc, &null); - heap_close(pg_shadow_rel, AccessExclusiveLock); - elog(ERROR, "DROP USER: user \"%s\" owns database \"%s\", cannot be removed%s", - user, nameout(DatumGetName(datum)), - (length(stmt->users) > 1) ? " (no users removed)" : "" - ); - } - - heap_endscan(scan); - heap_close(pg_rel, AccessExclusiveLock); - - /* - * Somehow we'd have to check for tables, views, etc. owned by the user - * as well, but those could be spread out over all sorts of databases - * which we don't have access to (easily). - */ - - /* - * Remove the user from the pg_shadow table - */ - heap_delete(pg_shadow_rel, &tuple->t_self, NULL); - - /* - * Remove user from groups - * - * try calling alter group drop user for every group - */ - pg_rel = heap_openr(GroupRelationName, AccessExclusiveLock); - pg_dsc = RelationGetDescr(pg_rel); - scan = heap_beginscan(pg_rel, false, SnapshotNow, 0, NULL); - while (HeapTupleIsValid(tmp_tuple = heap_getnext(scan, 0))) - { - AlterGroupStmt ags; - - datum = heap_getattr(tmp_tuple, Anum_pg_group_groname, pg_dsc, &null); - - ags.name = nameout(DatumGetName(datum)); /* the group name from which to try to drop the user */ - ags.action = -1; - ags.listUsers = lcons((void*)makeInteger(usesysid), NIL); - AlterGroup(&ags, "DROP USER"); - } - heap_endscan(scan); - heap_close(pg_rel, AccessExclusiveLock); - } + foreach(item, stmt->users) + { + HeapTuple tuple, + tmp_tuple; + Relation pg_rel; + TupleDesc pg_dsc; + ScanKeyData scankey; + HeapScanDesc scan; + Datum datum; + bool null; + int32 usesysid; + const char *user = strVal(lfirst(item)); + + tuple = SearchSysCacheTuple(SHADOWNAME, + PointerGetDatum(user), + 0, 0, 0); + if (!HeapTupleIsValid(tuple)) + { + heap_close(pg_shadow_rel, AccessExclusiveLock); + elog(ERROR, "DROP USER: user \"%s\" does not exist%s", user, + (length(stmt->users) > 1) ? " (no users removed)" : ""); + } + + usesysid = DatumGetInt32(heap_getattr(tuple, Anum_pg_shadow_usesysid, pg_shadow_dsc, &null)); + + /*------------------- + * Check if user still owns a database. If so, error out. + * + * (It used to be that this function would drop the database automatically. + * This is not only very dangerous for people that don't read the manual, + * it doesn't seem to be the behaviour one would expect either.) + * -- petere 2000/01/14) + *-------------------*/ + pg_rel = heap_openr(DatabaseRelationName, AccessExclusiveLock); + pg_dsc = RelationGetDescr(pg_rel); + + ScanKeyEntryInitialize(&scankey, 0x0, Anum_pg_database_datdba, F_INT4EQ, + Int32GetDatum(usesysid)); + + scan = heap_beginscan(pg_rel, false, SnapshotNow, 1, &scankey); + + if (HeapTupleIsValid(tmp_tuple = heap_getnext(scan, 0))) + { + datum = heap_getattr(tmp_tuple, Anum_pg_database_datname, pg_dsc, &null); + heap_close(pg_shadow_rel, AccessExclusiveLock); + elog(ERROR, "DROP USER: user \"%s\" owns database \"%s\", cannot be removed%s", + user, nameout(DatumGetName(datum)), + (length(stmt->users) > 1) ? " (no users removed)" : "" + ); + } + + heap_endscan(scan); + heap_close(pg_rel, AccessExclusiveLock); + + /* + * Somehow we'd have to check for tables, views, etc. owned by the + * user as well, but those could be spread out over all sorts of + * databases which we don't have access to (easily). + */ + + /* + * Remove the user from the pg_shadow table + */ + heap_delete(pg_shadow_rel, &tuple->t_self, NULL); + + /* + * Remove user from groups + * + * try calling alter group drop user for every group + */ + pg_rel = heap_openr(GroupRelationName, AccessExclusiveLock); + pg_dsc = RelationGetDescr(pg_rel); + scan = heap_beginscan(pg_rel, false, SnapshotNow, 0, NULL); + while (HeapTupleIsValid(tmp_tuple = heap_getnext(scan, 0))) + { + AlterGroupStmt ags; + + datum = heap_getattr(tmp_tuple, Anum_pg_group_groname, pg_dsc, &null); + + ags.name = nameout(DatumGetName(datum)); /* the group name from + * which to try to drop + * the user */ + ags.action = -1; + ags.listUsers = lcons((void *) makeInteger(usesysid), NIL); + AlterGroup(&ags, "DROP USER"); + } + heap_endscan(scan); + heap_close(pg_rel, AccessExclusiveLock); + } /* * Write the updated pg_shadow data to the flat password file. */ - write_password_file(pg_shadow_rel); + write_password_file(pg_shadow_rel); - /* - * Now we can clean up. - */ - heap_close(pg_shadow_rel, AccessExclusiveLock); + /* + * Now we can clean up. + */ + heap_close(pg_shadow_rel, AccessExclusiveLock); } @@ -609,7 +630,7 @@ CheckPgUserAclNotNull() 0, 0, 0); if (!HeapTupleIsValid(htup)) { - /* BIG problem */ + /* BIG problem */ elog(ERROR, "IsPgUserAclNull: \"%s\" not found", ShadowRelationName); } @@ -617,10 +638,10 @@ CheckPgUserAclNotNull() if (heap_attisnull(htup, Anum_pg_class_relacl)) { elog(ERROR, - "To use passwords, you have to revoke permissions on %s " - "so normal users cannot read the passwords. " - "Try 'REVOKE ALL ON \"%s\" FROM PUBLIC'.", - ShadowRelationName, ShadowRelationName); + "To use passwords, you have to revoke permissions on %s " + "so normal users cannot read the passwords. " + "Try 'REVOKE ALL ON \"%s\" FROM PUBLIC'.", + ShadowRelationName, ShadowRelationName); } return; @@ -637,14 +658,15 @@ CreateGroup(CreateGroupStmt *stmt) Relation pg_group_rel; HeapScanDesc scan; HeapTuple tuple; - TupleDesc pg_group_dsc; - bool group_exists = false, - sysid_exists = false; - int max_id = 0; - Datum new_record[Natts_pg_group]; - char new_record_nulls[Natts_pg_group]; - List *item, *newlist=NULL; - ArrayType *userarray; + TupleDesc pg_group_dsc; + bool group_exists = false, + sysid_exists = false; + int max_id = 0; + Datum new_record[Natts_pg_group]; + char new_record_nulls[Natts_pg_group]; + List *item, + *newlist = NULL; + ArrayType *userarray; /* * Make sure the user can do this. @@ -652,12 +674,12 @@ CreateGroup(CreateGroupStmt *stmt) if (!superuser()) elog(ERROR, "CREATE GROUP: permission denied"); - /* - * There is not real reason for this, but it makes it consistent - * with create user, and it seems like a good idea anyway. - */ + /* + * There is not real reason for this, but it makes it consistent with + * create user, and it seems like a good idea anyway. + */ if (IsTransactionBlock()) - elog(ERROR, "CREATE GROUP: may not be called in a transaction block"); + elog(ERROR, "CREATE GROUP: may not be called in a transaction block"); pg_group_rel = heap_openr(GroupRelationName, AccessExclusiveLock); @@ -666,111 +688,111 @@ CreateGroup(CreateGroupStmt *stmt) scan = heap_beginscan(pg_group_rel, false, SnapshotNow, 0, NULL); while (!group_exists && !sysid_exists && HeapTupleIsValid(tuple = heap_getnext(scan, false))) { - Datum datum; - bool null; + Datum datum; + bool null; datum = heap_getattr(tuple, Anum_pg_group_groname, pg_group_dsc, &null); group_exists = datum && !null && (strcmp((char *) datum, stmt->name) == 0); datum = heap_getattr(tuple, Anum_pg_group_grosysid, pg_group_dsc, &null); - if (stmt->sysid >= 0) /* customized id wanted */ - sysid_exists = datum && !null && ((int)datum == stmt->sysid); - else /* pick 1 + max */ - { - if ((int) datum > max_id) - max_id = (int) datum; - } + if (stmt->sysid >= 0) /* customized id wanted */ + sysid_exists = datum && !null && ((int) datum == stmt->sysid); + else +/* pick 1 + max */ + { + if ((int) datum > max_id) + max_id = (int) datum; + } } heap_endscan(scan); if (group_exists || sysid_exists) { heap_close(pg_group_rel, AccessExclusiveLock); - if (group_exists) - elog(ERROR, "CREATE GROUP: group name \"%s\" already exists", stmt->name); - else - elog(ERROR, "CREATE GROUP: group sysid %d is already assigned", stmt->sysid); + if (group_exists) + elog(ERROR, "CREATE GROUP: group name \"%s\" already exists", stmt->name); + else + elog(ERROR, "CREATE GROUP: group sysid %d is already assigned", stmt->sysid); } - /* - * Translate the given user names to ids - */ - - foreach(item, stmt->initUsers) - { - const char * groupuser = strVal(lfirst(item)); - Value *v; - - tuple = SearchSysCacheTuple(SHADOWNAME, - PointerGetDatum(groupuser), - 0, 0, 0); - if (!HeapTupleIsValid(tuple)) - { - heap_close(pg_group_rel, AccessExclusiveLock); - elog(ERROR, "CREATE GROUP: user \"%s\" does not exist", groupuser); - } - - v = makeInteger(((Form_pg_shadow) GETSTRUCT(tuple))->usesysid); - if (!member(v, newlist)) - newlist = lcons(v, newlist); - } - - /* build an array to insert */ - if (newlist) - { - int i; - - userarray = palloc(ARR_OVERHEAD(1) + length(newlist) * sizeof(int32)); - ARR_SIZE(userarray) = ARR_OVERHEAD(1) + length(newlist) * sizeof(int32); - ARR_FLAGS(userarray) = 0x0; - ARR_NDIM(userarray) = 1; /* one dimensional array */ - ARR_LBOUND(userarray)[0] = 1; /* axis starts at one */ - ARR_DIMS(userarray)[0] = length(newlist); /* axis is this long */ - /* fill the array */ - i = 0; - foreach(item, newlist) - { - ((int*)ARR_DATA_PTR(userarray))[i++] = intVal(lfirst(item)); - } - } - else - userarray = NULL; - - /* - * Form a tuple to insert - */ - if (stmt->sysid >=0) - max_id = stmt->sysid; - else - max_id++; - - new_record[Anum_pg_group_groname-1] = (Datum)(stmt->name); - new_record[Anum_pg_group_grosysid-1] = (Datum)(max_id); - new_record[Anum_pg_group_grolist-1] = (Datum)userarray; - - new_record_nulls[Anum_pg_group_groname-1] = ' '; - new_record_nulls[Anum_pg_group_grosysid-1] = ' '; - new_record_nulls[Anum_pg_group_grolist-1] = userarray ? ' ' : 'n'; - - tuple = heap_formtuple(pg_group_dsc, new_record, new_record_nulls); - - /* - * Insert a new record in the pg_group_table - */ - heap_insert(pg_group_rel, tuple); - - /* - * Update indexes - */ - if (RelationGetForm(pg_group_rel)->relhasindex) { - Relation idescs[Num_pg_group_indices]; - - CatalogOpenIndices(Num_pg_group_indices, - Name_pg_group_indices, idescs); - CatalogIndexInsert(idescs, Num_pg_group_indices, pg_group_rel, - tuple); - CatalogCloseIndices(Num_pg_group_indices, idescs); - } + /* + * Translate the given user names to ids + */ + + foreach(item, stmt->initUsers) + { + const char *groupuser = strVal(lfirst(item)); + Value *v; + + tuple = SearchSysCacheTuple(SHADOWNAME, + PointerGetDatum(groupuser), + 0, 0, 0); + if (!HeapTupleIsValid(tuple)) + { + heap_close(pg_group_rel, AccessExclusiveLock); + elog(ERROR, "CREATE GROUP: user \"%s\" does not exist", groupuser); + } + + v = makeInteger(((Form_pg_shadow) GETSTRUCT(tuple))->usesysid); + if (!member(v, newlist)) + newlist = lcons(v, newlist); + } + + /* build an array to insert */ + if (newlist) + { + int i; + + userarray = palloc(ARR_OVERHEAD(1) + length(newlist) * sizeof(int32)); + ARR_SIZE(userarray) = ARR_OVERHEAD(1) + length(newlist) * sizeof(int32); + ARR_FLAGS(userarray) = 0x0; + ARR_NDIM(userarray) = 1;/* one dimensional array */ + ARR_LBOUND(userarray)[0] = 1; /* axis starts at one */ + ARR_DIMS(userarray)[0] = length(newlist); /* axis is this long */ + /* fill the array */ + i = 0; + foreach(item, newlist) + ((int *) ARR_DATA_PTR(userarray))[i++] = intVal(lfirst(item)); + } + else + userarray = NULL; + + /* + * Form a tuple to insert + */ + if (stmt->sysid >= 0) + max_id = stmt->sysid; + else + max_id++; + + new_record[Anum_pg_group_groname - 1] = (Datum) (stmt->name); + new_record[Anum_pg_group_grosysid - 1] = (Datum) (max_id); + new_record[Anum_pg_group_grolist - 1] = (Datum) userarray; + + new_record_nulls[Anum_pg_group_groname - 1] = ' '; + new_record_nulls[Anum_pg_group_grosysid - 1] = ' '; + new_record_nulls[Anum_pg_group_grolist - 1] = userarray ? ' ' : 'n'; + + tuple = heap_formtuple(pg_group_dsc, new_record, new_record_nulls); + + /* + * Insert a new record in the pg_group_table + */ + heap_insert(pg_group_rel, tuple); + + /* + * Update indexes + */ + if (RelationGetForm(pg_group_rel)->relhasindex) + { + Relation idescs[Num_pg_group_indices]; + + CatalogOpenIndices(Num_pg_group_indices, + Name_pg_group_indices, idescs); + CatalogIndexInsert(idescs, Num_pg_group_indices, pg_group_rel, + tuple); + CatalogCloseIndices(Num_pg_group_indices, idescs); + } heap_close(pg_group_rel, AccessExclusiveLock); } @@ -781,258 +803,272 @@ CreateGroup(CreateGroupStmt *stmt) * ALTER GROUP */ void -AlterGroup(AlterGroupStmt *stmt, const char * tag) +AlterGroup(AlterGroupStmt *stmt, const char *tag) { Relation pg_group_rel; - TupleDesc pg_group_dsc; - HeapTuple group_tuple; + TupleDesc pg_group_dsc; + HeapTuple group_tuple; - /* + /* * Make sure the user can do this. */ if (!superuser()) elog(ERROR, "%s: permission denied", tag); - /* - * There is not real reason for this, but it makes it consistent - * with alter user, and it seems like a good idea anyway. - */ + /* + * There is not real reason for this, but it makes it consistent with + * alter user, and it seems like a good idea anyway. + */ if (IsTransactionBlock()) - elog(ERROR, "%s: may not be called in a transaction block", tag); + elog(ERROR, "%s: may not be called in a transaction block", tag); - pg_group_rel = heap_openr(GroupRelationName, AccessExclusiveLock); - pg_group_dsc = RelationGetDescr(pg_group_rel); + pg_group_rel = heap_openr(GroupRelationName, AccessExclusiveLock); + pg_group_dsc = RelationGetDescr(pg_group_rel); - /* - * Verify that group exists. - * If we find a tuple, will take that the rest of the way and make our - * modifications on it. - */ - if (!HeapTupleIsValid(group_tuple = SearchSysCacheTupleCopy(GRONAME, PointerGetDatum(stmt->name), 0, 0, 0))) + /* + * Verify that group exists. If we find a tuple, will take that the + * rest of the way and make our modifications on it. + */ + if (!HeapTupleIsValid(group_tuple = SearchSysCacheTupleCopy(GRONAME, PointerGetDatum(stmt->name), 0, 0, 0))) { - heap_close(pg_group_rel, AccessExclusiveLock); + heap_close(pg_group_rel, AccessExclusiveLock); elog(ERROR, "%s: group \"%s\" does not exist", tag, stmt->name); } - AssertState(stmt->action == +1 || stmt->action == -1); - /* - * Now decide what to do. - */ - if (stmt->action == +1) /* add users, might also be invoked by create user */ - { - Datum new_record[Natts_pg_group]; - char new_record_nulls[Natts_pg_group] = { ' ', ' ', ' '}; - ArrayType *newarray, *oldarray; - List * newlist = NULL, *item; - HeapTuple tuple; - bool null = false; - Datum datum = heap_getattr(group_tuple, Anum_pg_group_grolist, pg_group_dsc, &null); - int i; - - oldarray = (ArrayType*)datum; - Assert(null || ARR_NDIM(oldarray) == 1); - /* first add the old array to the hitherto empty list */ - if (!null) - for (i = ARR_LBOUND(oldarray)[0]; i < ARR_LBOUND(oldarray)[0] + ARR_DIMS(oldarray)[0]; i++) - { - int index, arrval; - Value *v; - bool valueNull; - index = i; - arrval = DatumGetInt32(array_ref(oldarray, 1, &index, true/*by value*/, - sizeof(int), 0, &valueNull)); - v = makeInteger(arrval); - /* filter out duplicates */ - if (!member(v, newlist)) - newlist = lcons(v, newlist); - } - - /* - * now convert the to be added usernames to sysids and add them - * to the list - */ - foreach(item, stmt->listUsers) - { - Value *v; - - if (strcmp(tag, "ALTER GROUP")==0) - { - /* Get the uid of the proposed user to add. */ - tuple = SearchSysCacheTuple(SHADOWNAME, - PointerGetDatum(strVal(lfirst(item))), - 0, 0, 0); - if (!HeapTupleIsValid(tuple)) - { - heap_close(pg_group_rel, AccessExclusiveLock); - elog(ERROR, "%s: user \"%s\" does not exist", tag, strVal(lfirst(item))); - } - v = makeInteger(((Form_pg_shadow) GETSTRUCT(tuple))->usesysid); - } - else if (strcmp(tag, "CREATE USER")==0) - { - /* in this case we already know the uid and it wouldn't - be in the cache anyway yet */ - v = lfirst(item); - } - else + AssertState(stmt->action == +1 || stmt->action == -1); + + /* + * Now decide what to do. + */ + if (stmt->action == +1) /* add users, might also be invoked by + * create user */ + { + Datum new_record[Natts_pg_group]; + char new_record_nulls[Natts_pg_group] = {' ', ' ', ' '}; + ArrayType *newarray, + *oldarray; + List *newlist = NULL, + *item; + HeapTuple tuple; + bool null = false; + Datum datum = heap_getattr(group_tuple, Anum_pg_group_grolist, pg_group_dsc, &null); + int i; + + oldarray = (ArrayType *) datum; + Assert(null || ARR_NDIM(oldarray) == 1); + /* first add the old array to the hitherto empty list */ + if (!null) + for (i = ARR_LBOUND(oldarray)[0]; i < ARR_LBOUND(oldarray)[0] + ARR_DIMS(oldarray)[0]; i++) + { + int index, + arrval; + Value *v; + bool valueNull; + + index = i; + arrval = DatumGetInt32(array_ref(oldarray, 1, &index, true /* by value */ , + sizeof(int), 0, &valueNull)); + v = makeInteger(arrval); + /* filter out duplicates */ + if (!member(v, newlist)) + newlist = lcons(v, newlist); + } + + /* + * now convert the to be added usernames to sysids and add them to + * the list + */ + foreach(item, stmt->listUsers) + { + Value *v; + + if (strcmp(tag, "ALTER GROUP") == 0) + { + /* Get the uid of the proposed user to add. */ + tuple = SearchSysCacheTuple(SHADOWNAME, + PointerGetDatum(strVal(lfirst(item))), + 0, 0, 0); + if (!HeapTupleIsValid(tuple)) + { + heap_close(pg_group_rel, AccessExclusiveLock); + elog(ERROR, "%s: user \"%s\" does not exist", tag, strVal(lfirst(item))); + } + v = makeInteger(((Form_pg_shadow) GETSTRUCT(tuple))->usesysid); + } + else if (strcmp(tag, "CREATE USER") == 0) { - elog(ERROR, "AlterGroup: unknown tag %s", tag); + + /* + * in this case we already know the uid and it wouldn't be + * in the cache anyway yet + */ + v = lfirst(item); + } + else + { + elog(ERROR, "AlterGroup: unknown tag %s", tag); v = NULL; /* keep compiler quiet */ } - if (!member(v, newlist)) - newlist = lcons(v, newlist); - else - /* we silently assume here that this error will only come up - in a ALTER GROUP statement */ - elog(NOTICE, "%s: user \"%s\" is already in group \"%s\"", tag, strVal(lfirst(item)), stmt->name); - } - - newarray = palloc(ARR_OVERHEAD(1) + length(newlist) * sizeof(int32)); - ARR_SIZE(newarray) = ARR_OVERHEAD(1) + length(newlist) * sizeof(int32); - ARR_FLAGS(newarray) = 0x0; - ARR_NDIM(newarray) = 1; /* one dimensional array */ - ARR_LBOUND(newarray)[0] = 1; /* axis starts at one */ - ARR_DIMS(newarray)[0] = length(newlist); /* axis is this long */ - /* fill the array */ - i = 0; - foreach(item, newlist) - { - ((int*)ARR_DATA_PTR(newarray))[i++] = intVal(lfirst(item)); - } - - /* - * Form a tuple with the new array and write it back. - */ - new_record[Anum_pg_group_groname-1] = (Datum)(stmt->name); - new_record[Anum_pg_group_grosysid-1] = heap_getattr(group_tuple, Anum_pg_group_grosysid, pg_group_dsc, &null); - new_record[Anum_pg_group_grolist-1] = PointerGetDatum(newarray); - - tuple = heap_formtuple(pg_group_dsc, new_record, new_record_nulls); - heap_update(pg_group_rel, &group_tuple->t_self, tuple, NULL); - - /* Update indexes */ - if (RelationGetForm(pg_group_rel)->relhasindex) { - Relation idescs[Num_pg_group_indices]; - - CatalogOpenIndices(Num_pg_group_indices, - Name_pg_group_indices, idescs); - CatalogIndexInsert(idescs, Num_pg_group_indices, pg_group_rel, - tuple); - CatalogCloseIndices(Num_pg_group_indices, idescs); - } - } /* endif alter group add user */ - - else if (stmt->action == -1) /*drop users from group */ - { - Datum datum; - bool null; - bool is_dropuser = strcmp(tag, "DROP USER")==0; - - datum = heap_getattr(group_tuple, Anum_pg_group_grolist, pg_group_dsc, &null); - if (null) - { - if (!is_dropuser) - elog(NOTICE, "ALTER GROUP: group \"%s\" does not have any members", stmt->name); - } - else - { - HeapTuple tuple; - Datum new_record[Natts_pg_group]; - char new_record_nulls[Natts_pg_group] = { ' ', ' ', ' '}; - ArrayType *oldarray, *newarray; - List * newlist = NULL, *item; - int i; - - oldarray = (ArrayType*)datum; - Assert(ARR_NDIM(oldarray) == 1); - /* first add the old array to the hitherto empty list */ - for (i = ARR_LBOUND(oldarray)[0]; i < ARR_LBOUND(oldarray)[0] + ARR_DIMS(oldarray)[0]; i++) - { - int index, arrval; - Value *v; - bool valueNull; - index = i; - arrval = DatumGetInt32(array_ref(oldarray, 1, &index, true/*by value*/, - sizeof(int), 0, &valueNull)); - v = makeInteger(arrval); - /* filter out duplicates */ - if (!member(v, newlist)) - newlist = lcons(v, newlist); - } - - /* - * now convert the to be dropped usernames to sysids and remove - * them from the list - */ - foreach(item, stmt->listUsers) - { - Value *v; - if (!is_dropuser) - { - /* Get the uid of the proposed user to drop. */ - tuple = SearchSysCacheTuple(SHADOWNAME, - PointerGetDatum(strVal(lfirst(item))), - 0, 0, 0); - if (!HeapTupleIsValid(tuple)) - { - heap_close(pg_group_rel, AccessExclusiveLock); - elog(ERROR, "ALTER GROUP: user \"%s\" does not exist", strVal(lfirst(item))); - } - v = makeInteger(((Form_pg_shadow) GETSTRUCT(tuple))->usesysid); - } - else - { - /* for dropuser we already know the uid */ - v = lfirst(item); - } - if (member(v, newlist)) - newlist = LispRemove(v, newlist); - else if (!is_dropuser) - elog(NOTICE, "ALTER GROUP: user \"%s\" is not in group \"%s\"", strVal(lfirst(item)), stmt->name); - } - - newarray = palloc(ARR_OVERHEAD(1) + length(newlist) * sizeof(int32)); - ARR_SIZE(newarray) = ARR_OVERHEAD(1) + length(newlist) * sizeof(int32); - ARR_FLAGS(newarray) = 0x0; - ARR_NDIM(newarray) = 1; /* one dimensional array */ - ARR_LBOUND(newarray)[0] = 1; /* axis starts at one */ - ARR_DIMS(newarray)[0] = length(newlist); /* axis is this long */ - /* fill the array */ - i = 0; - foreach(item, newlist) - { - ((int*)ARR_DATA_PTR(newarray))[i++] = intVal(lfirst(item)); - } - - /* - * Insert the new tuple with the updated user list - */ - new_record[Anum_pg_group_groname-1] = (Datum)(stmt->name); - new_record[Anum_pg_group_grosysid-1] = heap_getattr(group_tuple, Anum_pg_group_grosysid, pg_group_dsc, &null); - new_record[Anum_pg_group_grolist-1] = PointerGetDatum(newarray); - - tuple = heap_formtuple(pg_group_dsc, new_record, new_record_nulls); - heap_update(pg_group_rel, &group_tuple->t_self, tuple, NULL); - - /* Update indexes */ - if (RelationGetForm(pg_group_rel)->relhasindex) { - Relation idescs[Num_pg_group_indices]; - - CatalogOpenIndices(Num_pg_group_indices, - Name_pg_group_indices, idescs); - CatalogIndexInsert(idescs, Num_pg_group_indices, pg_group_rel, - tuple); - CatalogCloseIndices(Num_pg_group_indices, idescs); - } - - } /* endif group not null */ - } /* endif alter group drop user */ - - heap_close(pg_group_rel, AccessExclusiveLock); - - pfree(group_tuple); + if (!member(v, newlist)) + newlist = lcons(v, newlist); + else + + /* + * we silently assume here that this error will only come + * up in a ALTER GROUP statement + */ + elog(NOTICE, "%s: user \"%s\" is already in group \"%s\"", tag, strVal(lfirst(item)), stmt->name); + } + + newarray = palloc(ARR_OVERHEAD(1) + length(newlist) * sizeof(int32)); + ARR_SIZE(newarray) = ARR_OVERHEAD(1) + length(newlist) * sizeof(int32); + ARR_FLAGS(newarray) = 0x0; + ARR_NDIM(newarray) = 1; /* one dimensional array */ + ARR_LBOUND(newarray)[0] = 1; /* axis starts at one */ + ARR_DIMS(newarray)[0] = length(newlist); /* axis is this long */ + /* fill the array */ + i = 0; + foreach(item, newlist) + ((int *) ARR_DATA_PTR(newarray))[i++] = intVal(lfirst(item)); + + /* + * Form a tuple with the new array and write it back. + */ + new_record[Anum_pg_group_groname - 1] = (Datum) (stmt->name); + new_record[Anum_pg_group_grosysid - 1] = heap_getattr(group_tuple, Anum_pg_group_grosysid, pg_group_dsc, &null); + new_record[Anum_pg_group_grolist - 1] = PointerGetDatum(newarray); + + tuple = heap_formtuple(pg_group_dsc, new_record, new_record_nulls); + heap_update(pg_group_rel, &group_tuple->t_self, tuple, NULL); + + /* Update indexes */ + if (RelationGetForm(pg_group_rel)->relhasindex) + { + Relation idescs[Num_pg_group_indices]; + + CatalogOpenIndices(Num_pg_group_indices, + Name_pg_group_indices, idescs); + CatalogIndexInsert(idescs, Num_pg_group_indices, pg_group_rel, + tuple); + CatalogCloseIndices(Num_pg_group_indices, idescs); + } + } /* endif alter group add user */ + + else if (stmt->action == -1)/* drop users from group */ + { + Datum datum; + bool null; + bool is_dropuser = strcmp(tag, "DROP USER") == 0; + + datum = heap_getattr(group_tuple, Anum_pg_group_grolist, pg_group_dsc, &null); + if (null) + { + if (!is_dropuser) + elog(NOTICE, "ALTER GROUP: group \"%s\" does not have any members", stmt->name); + } + else + { + HeapTuple tuple; + Datum new_record[Natts_pg_group]; + char new_record_nulls[Natts_pg_group] = {' ', ' ', ' '}; + ArrayType *oldarray, + *newarray; + List *newlist = NULL, + *item; + int i; + + oldarray = (ArrayType *) datum; + Assert(ARR_NDIM(oldarray) == 1); + /* first add the old array to the hitherto empty list */ + for (i = ARR_LBOUND(oldarray)[0]; i < ARR_LBOUND(oldarray)[0] + ARR_DIMS(oldarray)[0]; i++) + { + int index, + arrval; + Value *v; + bool valueNull; + + index = i; + arrval = DatumGetInt32(array_ref(oldarray, 1, &index, true /* by value */ , + sizeof(int), 0, &valueNull)); + v = makeInteger(arrval); + /* filter out duplicates */ + if (!member(v, newlist)) + newlist = lcons(v, newlist); + } + + /* + * now convert the to be dropped usernames to sysids and + * remove them from the list + */ + foreach(item, stmt->listUsers) + { + Value *v; + + if (!is_dropuser) + { + /* Get the uid of the proposed user to drop. */ + tuple = SearchSysCacheTuple(SHADOWNAME, + PointerGetDatum(strVal(lfirst(item))), + 0, 0, 0); + if (!HeapTupleIsValid(tuple)) + { + heap_close(pg_group_rel, AccessExclusiveLock); + elog(ERROR, "ALTER GROUP: user \"%s\" does not exist", strVal(lfirst(item))); + } + v = makeInteger(((Form_pg_shadow) GETSTRUCT(tuple))->usesysid); + } + else + { + /* for dropuser we already know the uid */ + v = lfirst(item); + } + if (member(v, newlist)) + newlist = LispRemove(v, newlist); + else if (!is_dropuser) + elog(NOTICE, "ALTER GROUP: user \"%s\" is not in group \"%s\"", strVal(lfirst(item)), stmt->name); + } + + newarray = palloc(ARR_OVERHEAD(1) + length(newlist) * sizeof(int32)); + ARR_SIZE(newarray) = ARR_OVERHEAD(1) + length(newlist) * sizeof(int32); + ARR_FLAGS(newarray) = 0x0; + ARR_NDIM(newarray) = 1; /* one dimensional array */ + ARR_LBOUND(newarray)[0] = 1; /* axis starts at one */ + ARR_DIMS(newarray)[0] = length(newlist); /* axis is this long */ + /* fill the array */ + i = 0; + foreach(item, newlist) + ((int *) ARR_DATA_PTR(newarray))[i++] = intVal(lfirst(item)); + + /* + * Insert the new tuple with the updated user list + */ + new_record[Anum_pg_group_groname - 1] = (Datum) (stmt->name); + new_record[Anum_pg_group_grosysid - 1] = heap_getattr(group_tuple, Anum_pg_group_grosysid, pg_group_dsc, &null); + new_record[Anum_pg_group_grolist - 1] = PointerGetDatum(newarray); + + tuple = heap_formtuple(pg_group_dsc, new_record, new_record_nulls); + heap_update(pg_group_rel, &group_tuple->t_self, tuple, NULL); + + /* Update indexes */ + if (RelationGetForm(pg_group_rel)->relhasindex) + { + Relation idescs[Num_pg_group_indices]; + + CatalogOpenIndices(Num_pg_group_indices, + Name_pg_group_indices, idescs); + CatalogIndexInsert(idescs, Num_pg_group_indices, pg_group_rel, + tuple); + CatalogCloseIndices(Num_pg_group_indices, idescs); + } + + } /* endif group not null */ + } /* endif alter group drop user */ + + heap_close(pg_group_rel, AccessExclusiveLock); + + pfree(group_tuple); } @@ -1046,52 +1082,52 @@ DropGroup(DropGroupStmt *stmt) Relation pg_group_rel; HeapScanDesc scan; HeapTuple tuple; - TupleDesc pg_group_dsc; - bool gro_exists = false; + TupleDesc pg_group_dsc; + bool gro_exists = false; - /* + /* * Make sure the user can do this. */ if (!superuser()) elog(ERROR, "DROP GROUP: permission denied"); - /* - * There is not real reason for this, but it makes it consistent - * with drop user, and it seems like a good idea anyway. - */ + /* + * There is not real reason for this, but it makes it consistent with + * drop user, and it seems like a good idea anyway. + */ if (IsTransactionBlock()) - elog(ERROR, "DROP GROUP: may not be called in a transaction block"); + elog(ERROR, "DROP GROUP: may not be called in a transaction block"); - /* - * Scan the pg_group table and delete all matching groups. - */ + /* + * Scan the pg_group table and delete all matching groups. + */ pg_group_rel = heap_openr(GroupRelationName, AccessExclusiveLock); pg_group_dsc = RelationGetDescr(pg_group_rel); scan = heap_beginscan(pg_group_rel, false, SnapshotNow, 0, NULL); while (HeapTupleIsValid(tuple = heap_getnext(scan, false))) { - Datum datum; - bool null; - - datum = heap_getattr(tuple, Anum_pg_group_groname, pg_group_dsc, &null); - if (datum && !null && strcmp((char*)datum, stmt->name)==0) - { - gro_exists = true; - heap_delete(pg_group_rel, &tuple->t_self, NULL); - } + Datum datum; + bool null; + + datum = heap_getattr(tuple, Anum_pg_group_groname, pg_group_dsc, &null); + if (datum && !null && strcmp((char *) datum, stmt->name) == 0) + { + gro_exists = true; + heap_delete(pg_group_rel, &tuple->t_self, NULL); + } } heap_endscan(scan); - /* - * Did we find any? - */ - if (!gro_exists) - { - heap_close(pg_group_rel, AccessExclusiveLock); + /* + * Did we find any? + */ + if (!gro_exists) + { + heap_close(pg_group_rel, AccessExclusiveLock); elog(ERROR, "DROP GROUP: group \"%s\" does not exist", stmt->name); - } + } heap_close(pg_group_rel, AccessExclusiveLock); } diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 5c300c69398..834438b7986 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.146 2000/04/06 18:12:07 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.147 2000/04/12 17:14:59 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -102,15 +102,17 @@ static char *vc_show_rusage(struct rusage * ru0); /* * This routines handle a special cross-transaction portal. - * However it is automatically closed in case of abort. + * However it is automatically closed in case of abort. */ -void CommonSpecialPortalOpen(void) +void +CommonSpecialPortalOpen(void) { char *pname; if (CommonSpecialPortalInUse) elog(ERROR, "CommonSpecialPortal is in use"); + /* * Create a portal for safe memory across transactions. We need to * palloc the name space for it because our hash function expects the @@ -130,7 +132,8 @@ void CommonSpecialPortalOpen(void) CommonSpecialPortalInUse = true; } -void CommonSpecialPortalClose(void) +void +CommonSpecialPortalClose(void) { /* Clear flag first, to avoid recursion if PortalDrop elog's */ CommonSpecialPortalInUse = false; @@ -141,16 +144,18 @@ void CommonSpecialPortalClose(void) PortalDrop(&vc_portal); } -PortalVariableMemory CommonSpecialPortalGetMemory(void) +PortalVariableMemory +CommonSpecialPortalGetMemory(void) { return PortalGetVariableMemory(vc_portal); } -bool CommonSpecialPortalIsOpen(void) +bool +CommonSpecialPortalIsOpen(void) { return CommonSpecialPortalInUse; -} - +} + void vacuum(char *vacrel, bool verbose, bool analyze, List *va_spec) { @@ -208,9 +213,9 @@ vacuum(char *vacrel, bool verbose, bool analyze, List *va_spec) * Start up the vacuum cleaner. * * NOTE: since this commits the current transaction, the memory holding - * any passed-in parameters gets freed here. We must have already copied - * pass-by-reference parameters to safe storage. Don't make me fix this - * again! + * any passed-in parameters gets freed here. We must have already + * copied pass-by-reference parameters to safe storage. Don't make me + * fix this again! */ vc_init(); @@ -316,11 +321,12 @@ vc_getrels(NameData *VacRelP) if (NameStr(*VacRelP)) { + /* * we could use the cache here, but it is clearer to use scankeys * for both vacuum cases, bjm 2000/01/19 */ - char *nontemp_relname; + char *nontemp_relname; /* We must re-map temp table names bjm 2000-04-06 */ if ((nontemp_relname = @@ -414,7 +420,7 @@ vc_vacone(Oid relid, bool analyze, List *va_cols) int32 nindices, i; VRelStats *vacrelstats; - bool reindex = false; + bool reindex = false; StartTransactionCommand(); @@ -678,7 +684,7 @@ static void vc_scanheap(VRelStats *vacrelstats, Relation onerel, VPageList vacuum_pages, VPageList fraged_pages) { - BlockNumber nblocks, + BlockNumber nblocks, blkno; ItemId itemid; Buffer buf; @@ -1201,7 +1207,7 @@ vc_repair_frag(VRelStats *vacrelstats, Relation onerel, last_vacuum_block = -1; } if (num_fraged_pages > 0 && - fraged_pages->vpl_pagedesc[num_fraged_pages - 1]->vpd_blkno == + fraged_pages->vpl_pagedesc[num_fraged_pages - 1]->vpd_blkno == (BlockNumber) blkno) { /* page is in fraged_pages too; remove it */ @@ -1456,8 +1462,8 @@ vc_repair_frag(VRelStats *vacrelstats, Relation onerel, * we stop shrinking here. I could try to find * real parent row but want not to do it because * of real solution will be implemented anyway, - * latter, and we are too close to 6.5 release. - * - vadim 06/11/99 + * latter, and we are too close to 6.5 release. - + * vadim 06/11/99 */ if (Ptp.t_data->t_xmax != tp.t_data->t_xmin) { @@ -1539,20 +1545,23 @@ vc_repair_frag(VRelStats *vacrelstats, Relation onerel, * to get t_infomask of inserted heap tuple !!! */ ToPage = BufferGetPage(cur_buffer); + /* * If this page was not used before - clean it. * * This path is different from the other callers of * vc_vacpage, because we have already incremented the * vpd's vpd_offsets_used field to account for the - * tuple(s) we expect to move onto the page. Therefore - * vc_vacpage's check for vpd_offsets_used == 0 is wrong. - * But since that's a good debugging check for all other - * callers, we work around it here rather than remove it. + * tuple(s) we expect to move onto the page. Therefore + * vc_vacpage's check for vpd_offsets_used == 0 is + * wrong. But since that's a good debugging check for + * all other callers, we work around it here rather + * than remove it. */ if (!PageIsEmpty(ToPage) && vtmove[ti].cleanVpd) { - int sv_offsets_used = destvpd->vpd_offsets_used; + int sv_offsets_used = destvpd->vpd_offsets_used; + destvpd->vpd_offsets_used = 0; vc_vacpage(ToPage, destvpd); destvpd->vpd_offsets_used = sv_offsets_used; @@ -2267,7 +2276,7 @@ vc_attrstats(Relation onerel, VRelStats *vacrelstats, HeapTuple tuple) #ifdef _DROP_COLUMN_HACK__ if (COLUMN_IS_DROPPED(stats->attr)) continue; -#endif /* _DROP_COLUMN_HACK__ */ +#endif /* _DROP_COLUMN_HACK__ */ value = heap_getattr(tuple, stats->attr->attnum, tupDesc, &isnull); diff --git a/src/backend/commands/variable.c b/src/backend/commands/variable.c index 6432d3c2b8f..367b17aa64c 100644 --- a/src/backend/commands/variable.c +++ b/src/backend/commands/variable.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/variable.c,v 1.33 2000/04/07 13:39:24 thomas Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/variable.c,v 1.34 2000/04/12 17:15:00 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -436,7 +436,7 @@ parse_geqo(char *value) if (strcasecmp(tok, "on") == 0) { - int new_geqo_rels = GEQO_RELS; + int new_geqo_rels = GEQO_RELS; if (val != NULL) { @@ -505,7 +505,7 @@ static bool show_effective_cache_size() { elog(NOTICE, "EFFECTIVE_CACHE_SIZE is %g (%dK pages)", - effective_cache_size, BLCKSZ/1024); + effective_cache_size, BLCKSZ / 1024); return TRUE; } @@ -656,12 +656,12 @@ reset_cpu_operator_cost() * DATE_STYLE * * NOTE: set_default_datestyle() is called during backend startup to check - * if the PGDATESTYLE environment variable is set. We want the env var + * if the PGDATESTYLE environment variable is set. We want the env var * to determine the value that "RESET DateStyle" will reset to! */ /* These get initialized from the "master" values in init/globals.c */ -static int DefaultDateStyle; +static int DefaultDateStyle; static bool DefaultEuroDates; static bool @@ -777,8 +777,9 @@ set_default_datestyle(void) { char *DBDate; - /* Initialize from compile-time defaults in init/globals.c. - * NB: this is a necessary step; consider PGDATESTYLE="DEFAULT". + /* + * Initialize from compile-time defaults in init/globals.c. NB: this + * is a necessary step; consider PGDATESTYLE="DEFAULT". */ DefaultDateStyle = DateStyle; DefaultEuroDates = EuroDates; @@ -788,9 +789,11 @@ set_default_datestyle(void) if (DBDate == NULL) return; - /* Make a modifiable copy --- overwriting the env var doesn't seem + /* + * Make a modifiable copy --- overwriting the env var doesn't seem * like a good idea, even though we currently won't look at it again. - * Note that we cannot use palloc at this early stage of initialization. + * Note that we cannot use palloc at this early stage of + * initialization. */ DBDate = strdup(DBDate); @@ -1041,9 +1044,8 @@ reset_XactIsoLevel() static bool parse_pg_options(char *value) { - if (!superuser()) { + if (!superuser()) elog(ERROR, "Only users with superuser privilege can set pg_options"); - } if (value == NULL) read_pg_options(0); else @@ -1061,9 +1063,8 @@ show_pg_options(void) static bool reset_pg_options(void) { - if (!superuser()) { + if (!superuser()) elog(ERROR, "Only users with superuser privilege can set pg_options"); - } read_pg_options(0); return (TRUE); } @@ -1075,7 +1076,7 @@ reset_pg_options(void) static bool parse_random_seed(char *value) { - double seed = 0; + double seed = 0; if (value == NULL) reset_random_seed(); @@ -1097,7 +1098,7 @@ show_random_seed(void) static bool reset_random_seed(void) { - double seed = 0.5; + double seed = 0.5; setseed(&seed); return (TRUE); diff --git a/src/backend/executor/execAmi.c b/src/backend/executor/execAmi.c index cdde7c19801..579465bf0b8 100644 --- a/src/backend/executor/execAmi.c +++ b/src/backend/executor/execAmi.c @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: execAmi.c,v 1.45 2000/01/26 05:56:21 momjian Exp $ + * $Id: execAmi.c,v 1.46 2000/04/12 17:15:07 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -235,9 +235,10 @@ ExecCloseR(Plan *node) heap_endscan(scanDesc); /* - * endscan released AccessShareLock acquired by beginscan. If we are - * holding any stronger locks on the rel, they should be held till end of - * xact. Therefore, we need only close the rel and not release locks. + * endscan released AccessShareLock acquired by beginscan. If we are + * holding any stronger locks on the rel, they should be held till end + * of xact. Therefore, we need only close the rel and not release + * locks. */ if (relation != NULL) heap_close(relation, NoLock); @@ -423,7 +424,7 @@ ExecMarkPos(Plan *node) { switch (nodeTag(node)) { - case T_SeqScan: + case T_SeqScan: ExecSeqMarkPos((SeqScan *) node); break; diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index bbcba0fbc12..c879417baf6 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -27,7 +27,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.112 2000/04/07 07:24:47 vadim Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.113 2000/04/12 17:15:08 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -48,7 +48,7 @@ /* XXX no points for style */ extern TupleTableSlot *EvalPlanQual(EState *estate, Index rti, - ItemPointer tid); + ItemPointer tid); /* decls for local routines only used within this module */ static TupleDesc InitPlan(CmdType operation, @@ -75,13 +75,14 @@ static void ExecReplace(TupleTableSlot *slot, ItemPointer tupleid, static TupleTableSlot *EvalPlanQualNext(EState *estate); static void EndEvalPlanQual(EState *estate); static void ExecCheckQueryPerms(CmdType operation, Query *parseTree, - Plan *plan); + Plan *plan); static void ExecCheckPlanPerms(Plan *plan, CmdType operation, - int resultRelation, bool resultIsScanned); + int resultRelation, bool resultIsScanned); static void ExecCheckRTPerms(List *rangeTable, CmdType operation, - int resultRelation, bool resultIsScanned); + int resultRelation, bool resultIsScanned); static void ExecCheckRTEPerms(RangeTblEntry *rte, CmdType operation, - bool isResultRelation, bool resultIsScanned); + bool isResultRelation, bool resultIsScanned); + /* end of local decls */ @@ -460,14 +461,14 @@ ExecCheckPlanPerms(Plan *plan, CmdType operation, foreach(subp, plan->initPlan) { - SubPlan *subplan = (SubPlan *) lfirst(subp); + SubPlan *subplan = (SubPlan *) lfirst(subp); ExecCheckRTPerms(subplan->rtable, CMD_SELECT, 0, false); ExecCheckPlanPerms(subplan->plan, CMD_SELECT, 0, false); } foreach(subp, plan->subPlan) { - SubPlan *subplan = (SubPlan *) lfirst(subp); + SubPlan *subplan = (SubPlan *) lfirst(subp); ExecCheckRTPerms(subplan->rtable, CMD_SELECT, 0, false); ExecCheckPlanPerms(subplan->plan, CMD_SELECT, 0, false); @@ -485,49 +486,51 @@ ExecCheckPlanPerms(Plan *plan, CmdType operation, switch (nodeTag(plan)) { case T_Append: - { - Append *app = (Append *) plan; - List *appendplans; - - if (app->inheritrelid > 0) { - /* - * Append implements expansion of inheritance; all members - * of inheritrtable list will be plugged into same RTE slot. - * Therefore, they are either all result relations or none. - */ - List *rtable; + Append *app = (Append *) plan; + List *appendplans; - foreach(rtable, app->inheritrtable) + if (app->inheritrelid > 0) { - ExecCheckRTEPerms((RangeTblEntry *) lfirst(rtable), - operation, - (app->inheritrelid == resultRelation), - resultIsScanned); - } - } - else - { - /* Append implements UNION, which must be a SELECT */ - List *rtables; - foreach(rtables, app->unionrtables) + /* + * Append implements expansion of inheritance; all + * members of inheritrtable list will be plugged into + * same RTE slot. Therefore, they are either all + * result relations or none. + */ + List *rtable; + + foreach(rtable, app->inheritrtable) + { + ExecCheckRTEPerms((RangeTblEntry *) lfirst(rtable), + operation, + (app->inheritrelid == resultRelation), + resultIsScanned); + } + } + else { - ExecCheckRTPerms((List *) lfirst(rtables), - CMD_SELECT, 0, false); + /* Append implements UNION, which must be a SELECT */ + List *rtables; + + foreach(rtables, app->unionrtables) + { + ExecCheckRTPerms((List *) lfirst(rtables), + CMD_SELECT, 0, false); + } } - } - /* Check appended plans */ - foreach(appendplans, app->appendplans) - { - ExecCheckPlanPerms((Plan *) lfirst(appendplans), - operation, - resultRelation, - resultIsScanned); + /* Check appended plans */ + foreach(appendplans, app->appendplans) + { + ExecCheckPlanPerms((Plan *) lfirst(appendplans), + operation, + resultRelation, + resultIsScanned); + } + break; } - break; - } default: break; @@ -539,7 +542,7 @@ ExecCheckPlanPerms(Plan *plan, CmdType operation, * Check access permissions for all relations listed in a range table. * * If resultRelation is not 0, it is the RT index of the relation to be - * treated as the result relation. All other relations are assumed to be + * treated as the result relation. All other relations are assumed to be * read-only for the query. */ static void @@ -576,10 +579,11 @@ ExecCheckRTEPerms(RangeTblEntry *rte, CmdType operation, if (rte->skipAcl) { + /* - * This happens if the access to this table is due to a view - * query rewriting - the rewrite handler already checked the - * permissions against the view owner, so we just skip this entry. + * This happens if the access to this table is due to a view query + * rewriting - the rewrite handler already checked the permissions + * against the view owner, so we just skip this entry. */ return; } @@ -620,14 +624,12 @@ ExecCheckRTEPerms(RangeTblEntry *rte, CmdType operation, default: elog(ERROR, "ExecCheckRTEPerms: bogus operation %d", operation); - aclcheck_result = ACLCHECK_OK; /* keep compiler quiet */ + aclcheck_result = ACLCHECK_OK; /* keep compiler quiet */ break; } } else - { aclcheck_result = CHECK(ACL_RD); - } if (aclcheck_result != ACLCHECK_OK) elog(ERROR, "%s: %s", @@ -734,8 +736,9 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate) /* * If there are indices on the result relation, open them and save * descriptors in the result relation info, so that we can add new - * index entries for the tuples we add/update. We need not do this - * for a DELETE, however, since deletion doesn't affect indexes. + * index entries for the tuples we add/update. We need not do + * this for a DELETE, however, since deletion doesn't affect + * indexes. */ if (resultRelationDesc->rd_rel->relhasindex && operation != CMD_DELETE) @@ -805,10 +808,11 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate) targetList = plan->targetlist; /* - * Now that we have the target list, initialize the junk filter if needed. - * SELECT and INSERT queries need a filter if there are any junk attrs - * in the tlist. UPDATE and DELETE always need one, since there's always - * a junk 'ctid' attribute present --- no need to look first. + * Now that we have the target list, initialize the junk filter if + * needed. SELECT and INSERT queries need a filter if there are any + * junk attrs in the tlist. UPDATE and DELETE always need one, since + * there's always a junk 'ctid' attribute present --- no need to look + * first. */ { bool junk_filter_needed = false; @@ -948,8 +952,8 @@ EndPlan(Plan *plan, EState *estate) } /* - * close the result relations if necessary, - * but hold locks on them until xact commit + * close the result relations if necessary, but hold locks on them + * until xact commit */ if (resultRelationInfo != NULL) { @@ -1708,10 +1712,10 @@ ExecRelCheck(Relation rel, HeapTuple tuple, EState *estate) /* * NOTE: SQL92 specifies that a NULL result from a constraint - * expression is not to be treated as a failure. Therefore, - * tell ExecQual to return TRUE for NULL. + * expression is not to be treated as a failure. Therefore, tell + * ExecQual to return TRUE for NULL. */ - if (! ExecQual(qual, econtext, true)) + if (!ExecQual(qual, econtext, true)) return check[i].ccname; } @@ -1738,7 +1742,7 @@ ExecConstraints(char *caller, Relation rel, HeapTuple tuple, EState *estate) { if (rel->rd_att->attrs[attrChk - 1]->attnotnull && heap_attisnull(tuple, attrChk)) elog(ERROR, "%s: Fail to add null value in not null attribute %s", - caller, NameStr(rel->rd_att->attrs[attrChk - 1]->attname)); + caller, NameStr(rel->rd_att->attrs[attrChk - 1]->attname)); } } @@ -1791,7 +1795,7 @@ EvalPlanQual(EState *estate, Index rti, ItemPointer tid) Assert(oldepq->rti != 0); /* stop execution */ ExecEndNode(epq->plan, epq->plan); - epqstate->es_tupleTable->next = 0; + epqstate->es_tupleTable->next = 0; heap_freetuple(epqstate->es_evTuple[epq->rti - 1]); epqstate->es_evTuple[epq->rti - 1] = NULL; /* push current PQ to freePQ stack */ @@ -1861,7 +1865,7 @@ EvalPlanQual(EState *estate, Index rti, ItemPointer tid) if (endNode) { ExecEndNode(epq->plan, epq->plan); - epqstate->es_tupleTable->next = 0; + epqstate->es_tupleTable->next = 0; } /* free old RTE' tuple */ @@ -1949,10 +1953,10 @@ EvalPlanQual(EState *estate, Index rti, ItemPointer tid) estate->es_evalPlanQual = (Pointer) epq; } else - { - epq->rti = 0; /* this is the first (oldest) */ - estate->es_useEvalPlan = false; /* PQ - mark as free and */ - return (NULL); /* continue Query execution */ + { + epq->rti = 0; /* this is the first (oldest) */ + estate->es_useEvalPlan = false; /* PQ - mark as free and */ + return (NULL); /* continue Query execution */ } } @@ -1961,7 +1965,7 @@ EvalPlanQual(EState *estate, Index rti, ItemPointer tid) estate->es_origPlan->nParamExec * sizeof(ParamExecData)); memset(epqstate->es_evTupleNull, false, length(estate->es_range_table) * sizeof(bool)); - Assert(epqstate->es_tupleTable->next == 0); + Assert(epqstate->es_tupleTable->next == 0); ExecInitNode(epq->plan, epqstate, NULL); /* @@ -1992,16 +1996,16 @@ lpqnext:; if (TupIsNull(slot)) { ExecEndNode(epq->plan, epq->plan); - epqstate->es_tupleTable->next = 0; + epqstate->es_tupleTable->next = 0; heap_freetuple(epqstate->es_evTuple[epq->rti - 1]); epqstate->es_evTuple[epq->rti - 1] = NULL; /* pop old PQ from the stack */ oldepq = (evalPlanQual *) epqstate->es_evalPlanQual; if (oldepq == (evalPlanQual *) NULL) { - epq->rti = 0; /* this is the first (oldest) */ - estate->es_useEvalPlan = false; /* PQ - mark as free and */ - return (NULL); /* continue Query execution */ + epq->rti = 0; /* this is the first (oldest) */ + estate->es_useEvalPlan = false; /* PQ - mark as free and */ + return (NULL); /* continue Query execution */ } Assert(oldepq->rti != 0); /* push current PQ to freePQ stack */ @@ -2031,7 +2035,7 @@ EndEvalPlanQual(EState *estate) for (;;) { ExecEndNode(epq->plan, epq->plan); - epqstate->es_tupleTable->next = 0; + epqstate->es_tupleTable->next = 0; if (epqstate->es_evTuple[epq->rti - 1] != NULL) { heap_freetuple(epqstate->es_evTuple[epq->rti - 1]); @@ -2041,8 +2045,8 @@ EndEvalPlanQual(EState *estate) oldepq = (evalPlanQual *) epqstate->es_evalPlanQual; if (oldepq == (evalPlanQual *) NULL) { - epq->rti = 0; /* this is the first (oldest) */ - estate->es_useEvalPlan = false; /* PQ - mark as free */ + epq->rti = 0; /* this is the first (oldest) */ + estate->es_useEvalPlan = false; /* PQ - mark as free */ break; } Assert(oldepq->rti != 0); diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c index a319e2c2b37..58307e6a695 100644 --- a/src/backend/executor/execQual.c +++ b/src/backend/executor/execQual.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.68 2000/02/20 21:32:04 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.69 2000/04/12 17:15:08 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -108,12 +108,14 @@ ExecEvalArrayRef(ArrayRef *arrayRef, } else { - /* Null refexpr indicates we are doing an INSERT into an array column. - * For now, we just take the refassgnexpr (which the parser will have - * ensured is an array value) and return it as-is, ignoring any - * subscripts that may have been supplied in the INSERT column list. - * This is a kluge, but it's not real clear what the semantics ought - * to be... + + /* + * Null refexpr indicates we are doing an INSERT into an array + * column. For now, we just take the refassgnexpr (which the + * parser will have ensured is an array value) and return it + * as-is, ignoring any subscripts that may have been supplied in + * the INSERT column list. This is a kluge, but it's not real + * clear what the semantics ought to be... */ array_scanner = NULL; } @@ -153,16 +155,15 @@ ExecEvalArrayRef(ArrayRef *arrayRef, lIndex = lower.indx; } else - { lIndex = NULL; - } if (arrayRef->refassgnexpr != NULL) { - Datum sourceData = ExecEvalExpr(arrayRef->refassgnexpr, - econtext, - isNull, - &dummy); + Datum sourceData = ExecEvalExpr(arrayRef->refassgnexpr, + econtext, + isNull, + &dummy); + if (*isNull) return (Datum) NULL; @@ -209,7 +210,7 @@ ExecEvalArrayRef(ArrayRef *arrayRef, static Datum ExecEvalAggref(Aggref *aggref, ExprContext *econtext, bool *isNull) { - if (econtext->ecxt_aggvalues == NULL) /* safety check */ + if (econtext->ecxt_aggvalues == NULL) /* safety check */ elog(ERROR, "ExecEvalAggref: no aggregates in this expression context"); *isNull = econtext->ecxt_aggnulls[aggref->aggno]; @@ -281,7 +282,7 @@ ExecEvalVar(Var *variable, ExprContext *econtext, bool *isNull) Assert(attnum <= 0 || (attnum - 1 <= tuple_type->natts - 1 && tuple_type->attrs[attnum - 1] != NULL && - variable->vartype == tuple_type->attrs[attnum - 1]->atttypid)); + variable->vartype == tuple_type->attrs[attnum - 1]->atttypid)); /* * If the attribute number is invalid, then we are supposed to return @@ -633,7 +634,7 @@ ExecEvalFuncArgs(FunctionCachePtr fcache, */ argV[i] = ExecEvalExpr((Node *) lfirst(arg), econtext, - & nullVect[i], + &nullVect[i], argIsDone); if (!(*argIsDone)) @@ -779,9 +780,9 @@ ExecMakeFunctionResult(Node *node, result = postquel_function(funcNode, (char **) argV, isNull, isDone); - if (! *isDone) + if (!*isDone) break; /* got a result from current argument */ - if (! fcache->hasSetArg) + if (!fcache->hasSetArg) break; /* input not a set, so done */ /* OK, get the next argument... */ @@ -789,7 +790,11 @@ ExecMakeFunctionResult(Node *node, if (argDone) { - /* End of arguments, so reset the setArg flag and say "Done" */ + + /* + * End of arguments, so reset the setArg flag and say + * "Done" + */ fcache->setArg = (char *) NULL; fcache->hasSetArg = false; *isDone = true; @@ -797,7 +802,8 @@ ExecMakeFunctionResult(Node *node, break; } - /* If we reach here, loop around to run the function on the + /* + * If we reach here, loop around to run the function on the * new argument. */ } @@ -1003,20 +1009,22 @@ ExecEvalOr(Expr *orExpr, ExprContext *econtext, bool *isNull) AnyNull = false; /* - * If any of the clauses is TRUE, the OR result is TRUE regardless - * of the states of the rest of the clauses, so we can stop evaluating + * If any of the clauses is TRUE, the OR result is TRUE regardless of + * the states of the rest of the clauses, so we can stop evaluating * and return TRUE immediately. If none are TRUE and one or more is * NULL, we return NULL; otherwise we return FALSE. This makes sense * when you interpret NULL as "don't know": if we have a TRUE then the * OR is TRUE even if we aren't sure about some of the other inputs. * If all the known inputs are FALSE, but we have one or more "don't * knows", then we have to report that we "don't know" what the OR's - * result should be --- perhaps one of the "don't knows" would have been - * TRUE if we'd known its value. Only when all the inputs are known - * to be FALSE can we state confidently that the OR's result is FALSE. + * result should be --- perhaps one of the "don't knows" would have + * been TRUE if we'd known its value. Only when all the inputs are + * known to be FALSE can we state confidently that the OR's result is + * FALSE. */ foreach(clause, clauses) { + /* * We don't iterate over sets in the quals, so pass in an isDone * flag, but ignore it. @@ -1025,6 +1033,7 @@ ExecEvalOr(Expr *orExpr, ExprContext *econtext, bool *isNull) econtext, isNull, &isDone); + /* * if we have a non-null true result, then return it. */ @@ -1059,12 +1068,13 @@ ExecEvalAnd(Expr *andExpr, ExprContext *econtext, bool *isNull) * If any of the clauses is FALSE, the AND result is FALSE regardless * of the states of the rest of the clauses, so we can stop evaluating * and return FALSE immediately. If none are FALSE and one or more is - * NULL, we return NULL; otherwise we return TRUE. This makes sense + * NULL, we return NULL; otherwise we return TRUE. This makes sense * when you interpret NULL as "don't know", using the same sort of * reasoning as for OR, above. */ foreach(clause, clauses) { + /* * We don't iterate over sets in the quals, so pass in an isDone * flag, but ignore it. @@ -1073,6 +1083,7 @@ ExecEvalAnd(Expr *andExpr, ExprContext *econtext, bool *isNull) econtext, isNull, &isDone); + /* * if we have a non-null false result, then return it. */ @@ -1084,7 +1095,7 @@ ExecEvalAnd(Expr *andExpr, ExprContext *econtext, bool *isNull) /* AnyNull is true if at least one clause evaluated to NULL */ *isNull = AnyNull; - return (Datum) (! AnyNull); + return (Datum) (!AnyNull); } /* ---------------------------------------------------------------- @@ -1129,7 +1140,7 @@ ExecEvalCase(CaseExpr *caseExpr, ExprContext *econtext, bool *isNull) * case statement is satisfied. A NULL result from the test is * not considered true. */ - if (DatumGetInt32(clause_value) != 0 && ! *isNull) + if (DatumGetInt32(clause_value) != 0 && !*isNull) { return ExecEvalExpr(wclause->result, econtext, @@ -1258,7 +1269,7 @@ ExecEvalExpr(Node *expression, default: elog(ERROR, "ExecEvalExpr: unknown expression type %d", expr->opType); - retDatum = 0; /* keep compiler quiet */ + retDatum = 0; /* keep compiler quiet */ break; } break; @@ -1332,7 +1343,7 @@ ExecQual(List *qual, ExprContext *econtext, bool resultForNull) IncrProcessed(); /* - * Evaluate the qual conditions one at a time. If we find a FALSE + * Evaluate the qual conditions one at a time. If we find a FALSE * result, we can stop evaluating and return FALSE --- the AND result * must be FALSE. Also, if we find a NULL result when resultForNull * is FALSE, we can stop and return FALSE --- the AND result must be @@ -1353,14 +1364,15 @@ ExecQual(List *qual, ExprContext *econtext, bool resultForNull) /* * If there is a null clause, consider the qualification to fail. - * XXX is this still correct for constraints? It probably shouldn't - * happen at all ... + * XXX is this still correct for constraints? It probably + * shouldn't happen at all ... */ if (clause == NULL) return false; + /* - * pass isDone, but ignore it. We don't iterate over multiple returns - * in the qualifications. + * pass isDone, but ignore it. We don't iterate over multiple + * returns in the qualifications. */ expr_value = ExecEvalExpr(clause, econtext, &isNull, &isDone); @@ -1429,7 +1441,8 @@ ExecTargetList(List *targetlist, HeapTuple newTuple; bool isNull; bool haveDoneIters; - static struct tupleDesc NullTupleDesc; /* we assume this inits to zeroes */ + static struct tupleDesc NullTupleDesc; /* we assume this inits to + * zeroes */ /* * debugging stuff @@ -1512,7 +1525,8 @@ ExecTargetList(List *targetlist, if (itemIsDone[resind]) haveDoneIters = true; else - *isDone = false; /* we have undone Iters in the list */ + *isDone = false; /* we have undone Iters in the + * list */ } } else @@ -1571,7 +1585,9 @@ ExecTargetList(List *targetlist, { if (*isDone) { - /* all Iters are done, so return a null indicating tlist set + + /* + * all Iters are done, so return a null indicating tlist set * expansion is complete. */ newTuple = NULL; @@ -1579,21 +1595,24 @@ ExecTargetList(List *targetlist, } else { - /* We have some done and some undone Iters. Restart the done ones - * so that we can deliver a tuple (if possible). + + /* + * We have some done and some undone Iters. Restart the done + * ones so that we can deliver a tuple (if possible). * * XXX this code is a crock, because it only works for Iters at - * the top level of tlist expressions, and doesn't even work right - * for them: you should get all possible combinations of Iter - * results, but you won't unless the numbers of values returned by - * each are relatively prime. Should have a mechanism more like - * aggregate functions, where we make a list of all Iters - * contained in the tlist and cycle through their values in a - * methodical fashion. To do someday; can't get excited about - * fixing a Berkeley feature that's not in SQL92. (The only - * reason we're doing this much is that we have to be sure all - * the Iters are run to completion, or their subplan executors - * will have unreleased resources, e.g. pinned buffers...) + * the top level of tlist expressions, and doesn't even work + * right for them: you should get all possible combinations of + * Iter results, but you won't unless the numbers of values + * returned by each are relatively prime. Should have a + * mechanism more like aggregate functions, where we make a + * list of all Iters contained in the tlist and cycle through + * their values in a methodical fashion. To do someday; can't + * get excited about fixing a Berkeley feature that's not in + * SQL92. (The only reason we're doing this much is that we + * have to be sure all the Iters are run to completion, or + * their subplan executors will have unreleased resources, + * e.g. pinned buffers...) */ foreach(tl, targetlist) { @@ -1605,16 +1624,18 @@ ExecTargetList(List *targetlist, resdom = tle->resdom; resind = resdom->resno - 1; - if (IsA(expr, Iter) && itemIsDone[resind]) + if (IsA(expr, Iter) &&itemIsDone[resind]) { constvalue = (Datum) ExecEvalExpr(expr, econtext, &isNull, - &itemIsDone[resind]); + &itemIsDone[resind]); if (itemIsDone[resind]) { - /* Oh dear, this Iter is returning an empty set. - * Guess we can't make a tuple after all. + + /* + * Oh dear, this Iter is returning an empty + * set. Guess we can't make a tuple after all. */ *isDone = true; newTuple = NULL; @@ -1639,6 +1660,7 @@ ExecTargetList(List *targetlist, newTuple = (HeapTuple) heap_formtuple(targettype, values, null_head); exit: + /* * free the status arrays if we palloc'd them */ diff --git a/src/backend/executor/execTuples.c b/src/backend/executor/execTuples.c index 1cbae3519a9..578b8b80681 100644 --- a/src/backend/executor/execTuples.c +++ b/src/backend/executor/execTuples.c @@ -15,7 +15,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/execTuples.c,v 1.36 2000/01/27 18:11:27 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/execTuples.c,v 1.37 2000/04/12 17:15:08 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -188,8 +188,8 @@ ExecCreateTupleTable(int initialSize) /* initial number of slots in * -------------------------------- */ void -ExecDropTupleTable(TupleTable table, /* tuple table */ - bool shouldFree) /* true if we should free slot +ExecDropTupleTable(TupleTable table, /* tuple table */ + bool shouldFree) /* true if we should free slot * contents */ { int next; /* next available slot */ @@ -262,7 +262,7 @@ TupleTableSlot * /* return: the slot allocated in the tuple ExecAllocTableSlot(TupleTable table) { int slotnum; /* new slot number */ - TupleTableSlot* slot; + TupleTableSlot *slot; /* ---------------- * sanity checks @@ -335,8 +335,8 @@ ExecAllocTableSlot(TupleTable table) * * tuple: tuple to store * slot: slot to store it in - * buffer: disk buffer if tuple is in a disk page, else InvalidBuffer - * shouldFree: true if ExecClearTuple should pfree() the tuple + * buffer: disk buffer if tuple is in a disk page, else InvalidBuffer + * shouldFree: true if ExecClearTuple should pfree() the tuple * when done with it * * If 'buffer' is not InvalidBuffer, the tuple table code acquires a pin @@ -350,7 +350,7 @@ ExecAllocTableSlot(TupleTable table) * Another case where it is 'false' is when the referenced tuple is held * in a tuple table slot belonging to a lower-level executor Proc node. * In this case the lower-level slot retains ownership and responsibility - * for eventually releasing the tuple. When this method is used, we must + * for eventually releasing the tuple. When this method is used, we must * be certain that the upper-level Proc node will lose interest in the tuple * sooner than the lower-level one does! If you're not certain, copy the * lower-level tuple with heap_copytuple and let the upper-level table @@ -385,7 +385,8 @@ ExecStoreTuple(HeapTuple tuple, slot->ttc_buffer = buffer; slot->ttc_shouldFree = shouldFree; - /* If tuple is on a disk page, keep the page pinned as long as we hold + /* + * If tuple is on a disk page, keep the page pinned as long as we hold * a pointer into it. */ if (BufferIsValid(buffer)) @@ -426,7 +427,7 @@ ExecClearTuple(TupleTableSlot *slot) /* slot in which to store tuple */ slot->val = (HeapTuple) NULL; - slot->ttc_shouldFree = true; /* probably useless code... */ + slot->ttc_shouldFree = true;/* probably useless code... */ /* ---------------- * Drop the pin on the referenced buffer, if there is one. @@ -776,6 +777,7 @@ NodeGetResultTupleSlot(Plan *node) case T_TidScan: { CommonScanState *scanstate = ((IndexScan *) node)->scan.scanstate; + slot = scanstate->cstate.cs_ResultTupleSlot; } break; diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c index 8f15ac1ed18..e3783473f96 100644 --- a/src/backend/executor/execUtils.c +++ b/src/backend/executor/execUtils.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.54 2000/02/18 09:29:57 inoue Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.55 2000/04/12 17:15:08 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -776,7 +776,7 @@ ExecOpenIndices(Oid resultRelationOid, if (!RelationGetForm(resultRelationInfo->ri_RelationDesc)->relhasindex) return; if (IsIgnoringSystemIndexes() && - IsSystemRelationName(RelationGetRelationName(resultRelationInfo->ri_RelationDesc))) + IsSystemRelationName(RelationGetRelationName(resultRelationInfo->ri_RelationDesc))) return; /* ---------------- * open pg_index @@ -923,8 +923,8 @@ ExecOpenIndices(Oid resultRelationOid, /* * Hack for not btree and hash indices: they use relation - * level exclusive locking on update (i.e. - they are - * not ready for MVCC) and so we have to exclusively lock + * level exclusive locking on update (i.e. - they are not + * ready for MVCC) and so we have to exclusively lock * indices here to prevent deadlocks if we will scan them * - index_beginscan places AccessShareLock, indices * update methods don't use locks at all. We release this @@ -1186,7 +1186,7 @@ ExecInsertIndexTuples(TupleTableSlot *slot, econtext->ecxt_scantuple = slot; /* Skip this index-update if the predicate isn't satisfied */ - if (! ExecQual((List *) predicate, econtext, false)) + if (!ExecQual((List *) predicate, econtext, false)) continue; } diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c index 3854978029b..c8d119df482 100644 --- a/src/backend/executor/functions.c +++ b/src/backend/executor/functions.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.32 2000/04/04 21:44:39 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.33 2000/04/12 17:15:09 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -150,6 +150,7 @@ init_execution_state(FunctionCachePtr fcache, static TupleDesc postquel_start(execution_state *es) { + /* * Do nothing for utility commands. (create, destroy...) DZ - * 30-8-1996 @@ -166,9 +167,9 @@ postquel_getnext(execution_state *es) if (es->qd->operation == CMD_UTILITY) { + /* - * Process a utility command. (create, destroy...) DZ - - * 30-8-1996 + * Process a utility command. (create, destroy...) DZ - 30-8-1996 */ ProcessUtility(es->qd->parsetree->utilityStmt, es->qd->dest); if (!LAST_POSTQUEL_COMMAND(es)) @@ -184,6 +185,7 @@ postquel_getnext(execution_state *es) static void postquel_end(execution_state *es) { + /* * Do nothing for utility commands. (create, destroy...) DZ - * 30-8-1996 diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c index 961440cc66d..e2db06f84d1 100644 --- a/src/backend/executor/nodeAgg.c +++ b/src/backend/executor/nodeAgg.c @@ -15,7 +15,7 @@ * value1 = finalfunc(value1, value2) * * If initcond1 is NULL then the first non-NULL input_value is - * assigned directly to value1. sfunc1 isn't applied until value1 + * assigned directly to value1. sfunc1 isn't applied until value1 * is non-NULL. * * sfunc1 is never applied when the current tuple's input_value is NULL. @@ -24,7 +24,7 @@ * (usenulls was formerly used for COUNT(*), but is no longer needed for * that purpose; as of 10/1999 the support for usenulls is dead code. * I have not removed it because it seems like a potentially useful - * feature for user-defined aggregates. We'd just need to add a + * feature for user-defined aggregates. We'd just need to add a * flag column to pg_aggregate and a parameter to CREATE AGGREGATE...) * * @@ -32,7 +32,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/nodeAgg.c,v 1.62 2000/01/26 05:56:22 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/nodeAgg.c,v 1.63 2000/04/12 17:15:09 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -56,6 +56,7 @@ */ typedef struct AggStatePerAggData { + /* * These values are set up during ExecInitAgg() and do not change * thereafter: @@ -68,6 +69,7 @@ typedef struct AggStatePerAggData Oid xfn1_oid; Oid xfn2_oid; Oid finalfn_oid; + /* * fmgr lookup data for transfer functions --- only valid when * corresponding oid is not InvalidOid @@ -75,18 +77,21 @@ typedef struct AggStatePerAggData FmgrInfo xfn1; FmgrInfo xfn2; FmgrInfo finalfn; + /* - * Type of input data and Oid of sort operator to use for it; - * only set/used when aggregate has DISTINCT flag. (These are not - * used directly by nodeAgg, but must be passed to the Tuplesort object.) + * Type of input data and Oid of sort operator to use for it; only + * set/used when aggregate has DISTINCT flag. (These are not used + * directly by nodeAgg, but must be passed to the Tuplesort object.) */ Oid inputType; Oid sortOperator; + /* - * fmgr lookup data for input type's equality operator --- only set/used - * when aggregate has DISTINCT flag. + * fmgr lookup data for input type's equality operator --- only + * set/used when aggregate has DISTINCT flag. */ FmgrInfo equalfn; + /* * initial values from pg_aggregate entry */ @@ -94,6 +99,7 @@ typedef struct AggStatePerAggData Datum initValue2; /* for transtype2 */ bool initValue1IsNull, initValue2IsNull; + /* * We need the len and byval info for the agg's input and transition * data types in order to know how to copy/delete values. @@ -106,14 +112,14 @@ typedef struct AggStatePerAggData transtype2ByVal; /* - * These values are working state that is initialized at the start - * of an input tuple group and updated for each input tuple. + * These values are working state that is initialized at the start of + * an input tuple group and updated for each input tuple. * * For a simple (non DISTINCT) aggregate, we just feed the input values - * straight to the transition functions. If it's DISTINCT, we pass the - * input values into a Tuplesort object; then at completion of the input - * tuple group, we scan the sorted values, eliminate duplicates, and run - * the transition functions on the rest. + * straight to the transition functions. If it's DISTINCT, we pass + * the input values into a Tuplesort object; then at completion of the + * input tuple group, we scan the sorted values, eliminate duplicates, + * and run the transition functions on the rest. */ Tuplesortstate *sortstate; /* sort object, if a DISTINCT agg */ @@ -123,20 +129,22 @@ typedef struct AggStatePerAggData bool value1IsNull, value2IsNull; bool noInitValue; /* true if value1 not set yet */ + /* - * Note: right now, noInitValue always has the same value as value1IsNull. - * But we should keep them separate because once the fmgr interface is - * fixed, we'll need to distinguish a null returned by transfn1 from - * a null we haven't yet replaced with an input value. + * Note: right now, noInitValue always has the same value as + * value1IsNull. But we should keep them separate because once the + * fmgr interface is fixed, we'll need to distinguish a null returned + * by transfn1 from a null we haven't yet replaced with an input + * value. */ } AggStatePerAggData; -static void initialize_aggregate (AggStatePerAgg peraggstate); -static void advance_transition_functions (AggStatePerAgg peraggstate, - Datum newVal, bool isNull); -static void finalize_aggregate (AggStatePerAgg peraggstate, - Datum *resultVal, bool *resultIsNull); +static void initialize_aggregate(AggStatePerAgg peraggstate); +static void advance_transition_functions(AggStatePerAgg peraggstate, + Datum newVal, bool isNull); +static void finalize_aggregate(AggStatePerAgg peraggstate, + Datum *resultVal, bool *resultIsNull); static Datum copyDatum(Datum val, int typLen, bool typByVal); @@ -144,17 +152,19 @@ static Datum copyDatum(Datum val, int typLen, bool typByVal); * Initialize one aggregate for a new set of input values. */ static void -initialize_aggregate (AggStatePerAgg peraggstate) +initialize_aggregate(AggStatePerAgg peraggstate) { - Aggref *aggref = peraggstate->aggref; + Aggref *aggref = peraggstate->aggref; /* * Start a fresh sort operation for each DISTINCT aggregate. */ if (aggref->aggdistinct) { - /* In case of rescan, maybe there could be an uncompleted - * sort operation? Clean it up if so. + + /* + * In case of rescan, maybe there could be an uncompleted sort + * operation? Clean it up if so. */ if (peraggstate->sortstate) tuplesort_end(peraggstate->sortstate); @@ -169,8 +179,8 @@ initialize_aggregate (AggStatePerAgg peraggstate) * (Re)set value1 and value2 to their initial values. */ if (OidIsValid(peraggstate->xfn1_oid) && - ! peraggstate->initValue1IsNull) - peraggstate->value1 = copyDatum(peraggstate->initValue1, + !peraggstate->initValue1IsNull) + peraggstate->value1 = copyDatum(peraggstate->initValue1, peraggstate->transtype1Len, peraggstate->transtype1ByVal); else @@ -178,8 +188,8 @@ initialize_aggregate (AggStatePerAgg peraggstate) peraggstate->value1IsNull = peraggstate->initValue1IsNull; if (OidIsValid(peraggstate->xfn2_oid) && - ! peraggstate->initValue2IsNull) - peraggstate->value2 = copyDatum(peraggstate->initValue2, + !peraggstate->initValue2IsNull) + peraggstate->value2 = copyDatum(peraggstate->initValue2, peraggstate->transtype2Len, peraggstate->transtype2ByVal); else @@ -205,8 +215,8 @@ initialize_aggregate (AggStatePerAgg peraggstate) * out before reaching here. */ static void -advance_transition_functions (AggStatePerAgg peraggstate, - Datum newVal, bool isNull) +advance_transition_functions(AggStatePerAgg peraggstate, + Datum newVal, bool isNull) { Datum args[2]; @@ -214,6 +224,7 @@ advance_transition_functions (AggStatePerAgg peraggstate, { if (peraggstate->noInitValue) { + /* * value1 has not been initialized. This is the first non-NULL * input value. We use it as the initial value for value1. @@ -238,7 +249,7 @@ advance_transition_functions (AggStatePerAgg peraggstate, newVal = (Datum) fmgr_c(&peraggstate->xfn1, (FmgrValues *) args, &isNull); - if (! peraggstate->transtype1ByVal) + if (!peraggstate->transtype1ByVal) pfree(peraggstate->value1); peraggstate->value1 = newVal; } @@ -252,7 +263,7 @@ advance_transition_functions (AggStatePerAgg peraggstate, newVal = (Datum) fmgr_c(&peraggstate->xfn2, (FmgrValues *) args, &isNull); - if (! peraggstate->transtype2ByVal) + if (!peraggstate->transtype2ByVal) pfree(peraggstate->value2); peraggstate->value2 = newVal; } @@ -262,17 +273,18 @@ advance_transition_functions (AggStatePerAgg peraggstate, * Compute the final value of one aggregate. */ static void -finalize_aggregate (AggStatePerAgg peraggstate, - Datum *resultVal, bool *resultIsNull) +finalize_aggregate(AggStatePerAgg peraggstate, + Datum *resultVal, bool *resultIsNull) { Aggref *aggref = peraggstate->aggref; char *args[2]; /* * If it's a DISTINCT aggregate, all we've done so far is to stuff the - * input values into the sort object. Complete the sort, then run - * the transition functions on the non-duplicate values. Note that - * DISTINCT always suppresses nulls, per SQL spec, regardless of usenulls. + * input values into the sort object. Complete the sort, then run the + * transition functions on the non-duplicate values. Note that + * DISTINCT always suppresses nulls, per SQL spec, regardless of + * usenulls. */ if (aggref->aggdistinct) { @@ -289,41 +301,41 @@ finalize_aggregate (AggStatePerAgg peraggstate, continue; if (haveOldVal) { - Datum equal; + Datum equal; equal = (Datum) (*fmgr_faddr(&peraggstate->equalfn)) (oldVal, - newVal); + newVal); if (DatumGetInt32(equal) != 0) { - if (! peraggstate->inputtypeByVal) + if (!peraggstate->inputtypeByVal) pfree(DatumGetPointer(newVal)); continue; } } advance_transition_functions(peraggstate, newVal, false); - if (haveOldVal && ! peraggstate->inputtypeByVal) + if (haveOldVal && !peraggstate->inputtypeByVal) pfree(DatumGetPointer(oldVal)); oldVal = newVal; haveOldVal = true; } - if (haveOldVal && ! peraggstate->inputtypeByVal) + if (haveOldVal && !peraggstate->inputtypeByVal) pfree(DatumGetPointer(oldVal)); tuplesort_end(peraggstate->sortstate); peraggstate->sortstate = NULL; } /* - * Now apply the agg's finalfn, or substitute the appropriate transition - * value if there is no finalfn. + * Now apply the agg's finalfn, or substitute the appropriate + * transition value if there is no finalfn. * - * XXX For now, only apply finalfn if we got at least one - * non-null input value. This prevents zero divide in AVG(). - * If we had cleaner handling of null inputs/results in functions, - * we could probably take out this hack and define the result - * for no inputs as whatever finalfn returns for null input. + * XXX For now, only apply finalfn if we got at least one non-null input + * value. This prevents zero divide in AVG(). If we had cleaner + * handling of null inputs/results in functions, we could probably + * take out this hack and define the result for no inputs as whatever + * finalfn returns for null input. */ if (OidIsValid(peraggstate->finalfn_oid) && - ! peraggstate->noInitValue) + !peraggstate->noInitValue) { if (peraggstate->finalfn.fn_nargs > 1) { @@ -361,17 +373,17 @@ finalize_aggregate (AggStatePerAgg peraggstate, elog(ERROR, "ExecAgg: no valid transition functions??"); /* - * Release any per-group working storage, unless we're passing - * it back as the result of the aggregate. + * Release any per-group working storage, unless we're passing it back + * as the result of the aggregate. */ if (OidIsValid(peraggstate->xfn1_oid) && - ! peraggstate->value1IsNull && - ! peraggstate->transtype1ByVal) + !peraggstate->value1IsNull && + !peraggstate->transtype1ByVal) pfree(peraggstate->value1); - + if (OidIsValid(peraggstate->xfn2_oid) && - ! peraggstate->value2IsNull && - ! peraggstate->transtype2ByVal) + !peraggstate->value2IsNull && + !peraggstate->transtype2ByVal) pfree(peraggstate->value2); } @@ -383,8 +395,8 @@ finalize_aggregate (AggStatePerAgg peraggstate, * the appropriate attribute for each aggregate function use (Aggref * node) appearing in the targetlist or qual of the node. The number * of tuples to aggregate over depends on whether a GROUP BY clause is - * present. We can produce an aggregate result row per group, or just - * one for the whole query. The value of each aggregate is stored in + * present. We can produce an aggregate result row per group, or just + * one for the whole query. The value of each aggregate is stored in * the expression context to be used when ExecProject evaluates the * result tuple. * @@ -403,7 +415,7 @@ ExecAgg(Agg *node) ProjectionInfo *projInfo; Datum *aggvalues; bool *aggnulls; - AggStatePerAgg peragg; + AggStatePerAgg peragg; TupleTableSlot *resultSlot; HeapTuple inputTuple; int aggno; @@ -437,7 +449,7 @@ ExecAgg(Agg *node) */ for (aggno = 0; aggno < aggstate->numaggs; aggno++) { - AggStatePerAgg peraggstate = &peragg[aggno]; + AggStatePerAgg peraggstate = &peragg[aggno]; initialize_aggregate(peraggstate); } @@ -459,9 +471,9 @@ ExecAgg(Agg *node) for (aggno = 0; aggno < aggstate->numaggs; aggno++) { - AggStatePerAgg peraggstate = &peragg[aggno]; - Aggref *aggref = peraggstate->aggref; - Datum newVal; + AggStatePerAgg peraggstate = &peragg[aggno]; + Aggref *aggref = peraggstate->aggref; + Datum newVal; newVal = ExecEvalExpr(aggref->target, econtext, &isNull, &isDone); @@ -479,37 +491,37 @@ ExecAgg(Agg *node) /* * Keep a copy of the first input tuple for the projection. - * (We only need one since only the GROUP BY columns in it - * can be referenced, and these will be the same for all - * tuples aggregated over.) + * (We only need one since only the GROUP BY columns in it can + * be referenced, and these will be the same for all tuples + * aggregated over.) */ if (!inputTuple) inputTuple = heap_copytuple(outerslot->val); } /* - * Done scanning input tuple group. - * Finalize each aggregate calculation. + * Done scanning input tuple group. Finalize each aggregate + * calculation. */ for (aggno = 0; aggno < aggstate->numaggs; aggno++) { - AggStatePerAgg peraggstate = &peragg[aggno]; + AggStatePerAgg peraggstate = &peragg[aggno]; finalize_aggregate(peraggstate, - & aggvalues[aggno], & aggnulls[aggno]); + &aggvalues[aggno], &aggnulls[aggno]); } /* * If the outerPlan is a Group node, we will reach here after each * group. We are not done unless the Group node is done (a little - * ugliness here while we reach into the Group's state to find out). - * Furthermore, when grouping we return nothing at all unless we - * had some input tuple(s). By the nature of Group, there are - * no empty groups, so if we get here with no input the whole scan - * is empty. + * ugliness here while we reach into the Group's state to find + * out). Furthermore, when grouping we return nothing at all + * unless we had some input tuple(s). By the nature of Group, + * there are no empty groups, so if we get here with no input the + * whole scan is empty. * - * If the outerPlan isn't a Group, we are done when we get here, - * and we will emit a (single) tuple even if there were no input + * If the outerPlan isn't a Group, we are done when we get here, and + * we will emit a (single) tuple even if there were no input * tuples. */ if (IsA(outerPlan, Group)) @@ -523,17 +535,18 @@ ExecAgg(Agg *node) else { aggstate->agg_done = true; + /* - * If inputtuple==NULL (ie, the outerPlan didn't return anything), - * create a dummy all-nulls input tuple for use by execProject. - * 99.44% of the time this is a waste of cycles, because - * ordinarily the projected output tuple's targetlist cannot - * contain any direct (non-aggregated) references to input - * columns, so the dummy tuple will not be referenced. However - * there are special cases where this isn't so --- in particular - * an UPDATE involving an aggregate will have a targetlist - * reference to ctid. We need to return a null for ctid in that - * situation, not coredump. + * If inputtuple==NULL (ie, the outerPlan didn't return + * anything), create a dummy all-nulls input tuple for use by + * execProject. 99.44% of the time this is a waste of cycles, + * because ordinarily the projected output tuple's targetlist + * cannot contain any direct (non-aggregated) references to + * input columns, so the dummy tuple will not be referenced. + * However there are special cases where this isn't so --- in + * particular an UPDATE involving an aggregate will have a + * targetlist reference to ctid. We need to return a null for + * ctid in that situation, not coredump. * * The values returned for the aggregates will be the initial * values of the transition functions. @@ -550,7 +563,7 @@ ExecAgg(Agg *node) /* watch out for null input tuples, though... */ if (tupType && tupValue) { - null_array = (char *) palloc(sizeof(char)*tupType->natts); + null_array = (char *) palloc(sizeof(char) * tupType->natts); for (attnum = 0; attnum < tupType->natts; attnum++) null_array[attnum] = 'n'; inputTuple = heap_formtuple(tupType, tupValue, null_array); @@ -571,17 +584,17 @@ ExecAgg(Agg *node) /* * Form a projection tuple using the aggregate results and the - * representative input tuple. Store it in the result tuple slot. + * representative input tuple. Store it in the result tuple slot. */ resultSlot = ExecProject(projInfo, &isDone); /* - * If the completed tuple does not match the qualifications, - * it is ignored and we loop back to try to process another group. + * If the completed tuple does not match the qualifications, it is + * ignored and we loop back to try to process another group. * Otherwise, return the tuple. */ } - while (! ExecQual(node->plan.qual, econtext, false)); + while (!ExecQual(node->plan.qual, econtext, false)); return resultSlot; } @@ -596,13 +609,13 @@ ExecAgg(Agg *node) bool ExecInitAgg(Agg *node, EState *estate, Plan *parent) { - AggState *aggstate; - AggStatePerAgg peragg; - Plan *outerPlan; - ExprContext *econtext; - int numaggs, - aggno; - List *alist; + AggState *aggstate; + AggStatePerAgg peragg; + Plan *outerPlan; + ExprContext *econtext; + int numaggs, + aggno; + List *alist; /* * assign the node's execution state @@ -620,21 +633,23 @@ ExecInitAgg(Agg *node, EState *estate, Plan *parent) * find aggregates in targetlist and quals * * Note: pull_agg_clauses also checks that no aggs contain other agg - * calls in their arguments. This would make no sense under SQL semantics - * anyway (and it's forbidden by the spec). Because that is true, we - * don't need to worry about evaluating the aggs in any particular order. + * calls in their arguments. This would make no sense under SQL + * semantics anyway (and it's forbidden by the spec). Because that is + * true, we don't need to worry about evaluating the aggs in any + * particular order. */ aggstate->aggs = nconc(pull_agg_clause((Node *) node->plan.targetlist), pull_agg_clause((Node *) node->plan.qual)); aggstate->numaggs = numaggs = length(aggstate->aggs); if (numaggs <= 0) { + /* - * This used to be treated as an error, but we can't do that anymore - * because constant-expression simplification could optimize away - * all of the Aggrefs in the targetlist and qual. So, just make a - * debug note, and force numaggs positive so that palloc()s below - * don't choke. + * This used to be treated as an error, but we can't do that + * anymore because constant-expression simplification could + * optimize away all of the Aggrefs in the targetlist and qual. + * So, just make a debug note, and force numaggs positive so that + * palloc()s below don't choke. */ elog(DEBUG, "ExecInitAgg: could not find any aggregate functions"); numaggs = 1; @@ -655,8 +670,8 @@ ExecInitAgg(Agg *node, EState *estate, Plan *parent) ExecInitResultTupleSlot(estate, &aggstate->csstate.cstate); /* - * Set up aggregate-result storage in the expr context, - * and also allocate my private per-agg working storage + * Set up aggregate-result storage in the expr context, and also + * allocate my private per-agg working storage */ econtext = aggstate->csstate.cstate.cs_ExprContext; econtext->ecxt_aggvalues = (Datum *) palloc(sizeof(Datum) * numaggs); @@ -693,15 +708,15 @@ ExecInitAgg(Agg *node, EState *estate, Plan *parent) aggno = -1; foreach(alist, aggstate->aggs) { - Aggref *aggref = (Aggref *) lfirst(alist); - AggStatePerAgg peraggstate = &peragg[++aggno]; - char *aggname = aggref->aggname; - HeapTuple aggTuple; + Aggref *aggref = (Aggref *) lfirst(alist); + AggStatePerAgg peraggstate = &peragg[++aggno]; + char *aggname = aggref->aggname; + HeapTuple aggTuple; Form_pg_aggregate aggform; - Type typeInfo; - Oid xfn1_oid, - xfn2_oid, - finalfn_oid; + Type typeInfo; + Oid xfn1_oid, + xfn2_oid, + finalfn_oid; /* Mark Aggref node with its associated index in the result array */ aggref->aggno = aggno; @@ -762,9 +777,7 @@ ExecInitAgg(Agg *node, EState *estate, Plan *parent) } if (OidIsValid(finalfn_oid)) - { fmgr_info(finalfn_oid, &peraggstate->finalfn); - } if (aggref->aggdistinct) { @@ -848,7 +861,7 @@ copyDatum(Datum val, int typLen, bool typByVal) return val; else { - char *newVal; + char *newVal; if (typLen == -1) /* variable length type? */ typLen = VARSIZE((struct varlena *) DatumGetPointer(val)); diff --git a/src/backend/executor/nodeAppend.c b/src/backend/executor/nodeAppend.c index f5c5701fd25..1200d9e6ba9 100644 --- a/src/backend/executor/nodeAppend.c +++ b/src/backend/executor/nodeAppend.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/nodeAppend.c,v 1.29 2000/01/26 05:56:22 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/nodeAppend.c,v 1.30 2000/04/12 17:15:09 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -251,9 +251,9 @@ ExecInitAppend(Append *node, EState *estate, Plan *parent) foreach(rtentryP, rtable) { - RangeTblEntry *rtentry = lfirst(rtentryP); - Oid reloid; - RelationInfo *rri; + RangeTblEntry *rtentry = lfirst(rtentryP); + Oid reloid; + RelationInfo *rri; reloid = rtentry->relid; rri = makeNode(RelationInfo); @@ -304,6 +304,7 @@ ExecInitAppend(Append *node, EState *estate, Plan *parent) { JunkFilter *j = ExecInitJunkFilter(initNode->targetlist, ExecGetTupType(initNode)); + junkList = lappend(junkList, j); } diff --git a/src/backend/executor/nodeGroup.c b/src/backend/executor/nodeGroup.c index cad023776d8..1a35ea578e9 100644 --- a/src/backend/executor/nodeGroup.c +++ b/src/backend/executor/nodeGroup.c @@ -15,7 +15,7 @@ * locate group boundaries. * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/nodeGroup.c,v 1.33 2000/01/27 18:11:27 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/nodeGroup.c,v 1.34 2000/04/12 17:15:09 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -97,8 +97,9 @@ ExecGroupEveryTuple(Group *node) { grpstate->grp_useFirstTuple = FALSE; - /* note we rely on subplan to hold ownership of the tuple - * for as long as we need it; we don't copy it. + /* + * note we rely on subplan to hold ownership of the tuple for as + * long as we need it; we don't copy it. */ ExecStoreTuple(grpstate->grp_firstTuple, grpstate->csstate.css_ScanTupleSlot, @@ -122,17 +123,20 @@ ExecGroupEveryTuple(Group *node) } else { + /* * Compare with first tuple and see if this tuple is of the * same group. */ - if (! execTuplesMatch(firsttuple, outerTuple, - tupdesc, - node->numCols, node->grpColIdx, - grpstate->eqfunctions)) + if (!execTuplesMatch(firsttuple, outerTuple, + tupdesc, + node->numCols, node->grpColIdx, + grpstate->eqfunctions)) { + /* - * No; save the tuple to return it next time, and return NULL + * No; save the tuple to return it next time, and return + * NULL */ grpstate->grp_useFirstTuple = TRUE; heap_freetuple(firsttuple); @@ -142,8 +146,9 @@ ExecGroupEveryTuple(Group *node) } } - /* note we rely on subplan to hold ownership of the tuple - * for as long as we need it; we don't copy it. + /* + * note we rely on subplan to hold ownership of the tuple for as + * long as we need it; we don't copy it. */ ExecStoreTuple(outerTuple, grpstate->csstate.css_ScanTupleSlot, @@ -227,13 +232,13 @@ ExecGroupOneTuple(Group *node) outerTuple = outerslot->val; /* - * Compare with first tuple and see if this tuple is of the - * same group. + * Compare with first tuple and see if this tuple is of the same + * group. */ - if (! execTuplesMatch(firsttuple, outerTuple, - tupdesc, - node->numCols, node->grpColIdx, - grpstate->eqfunctions)) + if (!execTuplesMatch(firsttuple, outerTuple, + tupdesc, + node->numCols, node->grpColIdx, + grpstate->eqfunctions)) break; } @@ -244,8 +249,9 @@ ExecGroupOneTuple(Group *node) */ projInfo = grpstate->csstate.cstate.cs_ProjInfo; - /* note we rely on subplan to hold ownership of the tuple - * for as long as we need it; we don't copy it. + /* + * note we rely on subplan to hold ownership of the tuple for as long + * as we need it; we don't copy it. */ ExecStoreTuple(firsttuple, grpstate->csstate.css_ScanTupleSlot, @@ -418,7 +424,7 @@ execTuplesMatch(HeapTuple tuple1, * start comparing at the last field (least significant sort key). * That's the most likely to be different... */ - for (i = numCols; --i >= 0; ) + for (i = numCols; --i >= 0;) { AttrNumber att = matchColIdx[i]; Datum attr1, @@ -445,7 +451,7 @@ execTuplesMatch(HeapTuple tuple1, /* Apply the type-specific equality function */ - equal = (Datum) (*fmgr_faddr(& eqfunctions[i])) (attr1, attr2); + equal = (Datum) (*fmgr_faddr(&eqfunctions[i])) (attr1, attr2); if (DatumGetInt32(equal) == 0) return FALSE; @@ -459,7 +465,7 @@ execTuplesMatch(HeapTuple tuple1, * Look up the equality functions needed for execTuplesMatch. * The result is a palloc'd array. */ -FmgrInfo * +FmgrInfo * execTuplesMatchPrepare(TupleDesc tupdesc, int numCols, AttrNumber *matchColIdx) @@ -481,7 +487,7 @@ execTuplesMatchPrepare(TupleDesc tupdesc, typeidTypeName(typid)); } pgopform = (Form_pg_operator) GETSTRUCT(eq_operator); - fmgr_info(pgopform->oprcode, & eqfunctions[i]); + fmgr_info(pgopform->oprcode, &eqfunctions[i]); } return eqfunctions; diff --git a/src/backend/executor/nodeIndexscan.c b/src/backend/executor/nodeIndexscan.c index 16fcd225a8e..d6fdce309de 100644 --- a/src/backend/executor/nodeIndexscan.c +++ b/src/backend/executor/nodeIndexscan.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.48 2000/04/07 00:30:41 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.49 2000/04/12 17:15:09 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -106,7 +106,7 @@ IndexNext(IndexScan *node) direction = BackwardScanDirection; else if (ScanDirectionIsBackward(direction)) direction = ForwardScanDirection; - } + } snapshot = estate->es_snapshot; scanstate = node->scan.scanstate; indexstate = node->indxstate; @@ -195,11 +195,11 @@ IndexNext(IndexScan *node) List *qual; /* - * store the scanned tuple in the scan tuple slot of - * the scan state. Eventually we will only do this and not - * return a tuple. Note: we pass 'false' because tuples - * returned by amgetnext are pointers onto disk pages and - * must not be pfree()'d. + * store the scanned tuple in the scan tuple slot of the + * scan state. Eventually we will only do this and not + * return a tuple. Note: we pass 'false' because tuples + * returned by amgetnext are pointers onto disk pages and + * must not be pfree()'d. */ ExecStoreTuple(tuple, /* tuple to store */ slot, /* slot to store in */ @@ -208,16 +208,17 @@ IndexNext(IndexScan *node) /* * At this point we have an extra pin on the buffer, - * because ExecStoreTuple incremented the pin count. - * Drop our local pin. + * because ExecStoreTuple incremented the pin count. Drop + * our local pin. */ ReleaseBuffer(buffer); /* * We must check to see if the current tuple was already - * matched by an earlier index, so we don't double-report it. - * We do this by passing the tuple through ExecQual and - * checking for failure with all previous qualifications. + * matched by an earlier index, so we don't double-report + * it. We do this by passing the tuple through ExecQual + * and checking for failure with all previous + * qualifications. */ scanstate->cstate.cs_ExprContext->ecxt_scantuple = slot; qual = node->indxqualorig; @@ -234,7 +235,7 @@ IndexNext(IndexScan *node) qual = lnext(qual); } if (!prev_matches) - return slot; /* OK to return tuple */ + return slot;/* OK to return tuple */ /* Duplicate tuple, so drop it and loop back for another */ ExecClearTuple(slot); } @@ -380,13 +381,14 @@ ExecIndexReScan(IndexScan *node, ExprContext *exprCtxt, Plan *parent) scanexpr = (run_keys[j] == RIGHT_OP) ? (Node *) get_rightop(clause) : (Node *) get_leftop(clause); + /* * pass in isDone but ignore it. We don't iterate in * quals */ scanvalue = (Datum) ExecEvalExpr(scanexpr, - node->scan.scanstate->cstate.cs_ExprContext, + node->scan.scanstate->cstate.cs_ExprContext, &isNull, &isDone); scan_keys[j].sk_argument = scanvalue; if (isNull) @@ -750,7 +752,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent) clause = nth(j, qual); op = (Oper *) clause->oper; - if (!IsA(clause, Expr) || !IsA(op, Oper)) + if (!IsA(clause, Expr) ||!IsA(op, Oper)) elog(ERROR, "ExecInitIndexScan: indxqual not an opclause!"); opid = op->opid; @@ -801,7 +803,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent) Assert(leftop != NULL); - if (IsA(leftop, Var) && var_is_rel((Var *) leftop)) + if (IsA(leftop, Var) &&var_is_rel((Var *) leftop)) { /* ---------------- * if the leftop is a "rel-var", then it means @@ -884,7 +886,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent) Assert(rightop != NULL); - if (IsA(rightop, Var) && var_is_rel((Var *) rightop)) + if (IsA(rightop, Var) &&var_is_rel((Var *) rightop)) { /* ---------------- * here we make sure only one op identifies the @@ -1049,10 +1051,8 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent) ¤tRelation, /* return: rel desc */ (Pointer *) ¤tScanDesc); /* return: scan desc */ -if (!RelationGetForm(currentRelation)->relhasindex) -{ - elog(ERROR, "indexes of the relation %u was inactivated", reloid); -} + if (!RelationGetForm(currentRelation)->relhasindex) + elog(ERROR, "indexes of the relation %u was inactivated", reloid); scanstate->css_currentRelation = currentRelation; scanstate->css_currentScanDesc = currentScanDesc; diff --git a/src/backend/executor/nodeSort.c b/src/backend/executor/nodeSort.c index 9a70851e9f7..362aef88d3a 100644 --- a/src/backend/executor/nodeSort.c +++ b/src/backend/executor/nodeSort.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/nodeSort.c,v 1.25 2000/01/26 05:56:23 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/nodeSort.c,v 1.26 2000/04/12 17:15:09 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -126,7 +126,7 @@ ExecSort(Sort *node) * ---------------- */ - if (! sortstate->sort_Done) + if (!sortstate->sort_Done) { Plan *outerNode; TupleDesc tupDesc; @@ -156,7 +156,7 @@ ExecSort(Sort *node) sortkeys = (ScanKey) sortstate->sort_Keys; tuplesortstate = tuplesort_begin_heap(tupDesc, keycount, sortkeys, - true /* randomAccess */); + true /* randomAccess */ ); sortstate->tuplesortstate = (void *) tuplesortstate; @@ -371,7 +371,7 @@ ExecSortMarkPos(Sort *node) * if we haven't sorted yet, just return * ---------------- */ - if (! sortstate->sort_Done) + if (!sortstate->sort_Done) return; tuplesort_markpos((Tuplesortstate *) sortstate->tuplesortstate); @@ -392,7 +392,7 @@ ExecSortRestrPos(Sort *node) * if we haven't sorted yet, just return. * ---------------- */ - if (! sortstate->sort_Done) + if (!sortstate->sort_Done) return; /* ---------------- @@ -412,14 +412,14 @@ ExecReScanSort(Sort *node, ExprContext *exprCtxt, Plan *parent) * not NULL then it will be re-scanned by ExecProcNode, else - no * reason to re-scan it at all. */ - if (! sortstate->sort_Done) + if (!sortstate->sort_Done) return; ExecClearTuple(sortstate->csstate.cstate.cs_ResultTupleSlot); /* - * If subnode is to be rescanned then we forget previous sort - * results; we have to re-read the subplan and re-sort. + * If subnode is to be rescanned then we forget previous sort results; + * we have to re-read the subplan and re-sort. * * Otherwise we can just rewind and rescan the sorted output. */ @@ -430,7 +430,5 @@ ExecReScanSort(Sort *node, ExprContext *exprCtxt, Plan *parent) sortstate->tuplesortstate = NULL; } else - { tuplesort_rescan((Tuplesortstate *) sortstate->tuplesortstate); - } } diff --git a/src/backend/executor/nodeSubplan.c b/src/backend/executor/nodeSubplan.c index ed09a0bc9f2..99b09f685a0 100644 --- a/src/backend/executor/nodeSubplan.c +++ b/src/backend/executor/nodeSubplan.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/nodeSubplan.c,v 1.24 2000/03/23 07:32:58 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/nodeSubplan.c,v 1.25 2000/04/12 17:15:10 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -67,20 +67,20 @@ ExecSubPlan(SubPlan *node, List *pvar, ExprContext *econtext, bool *isNull) ExecReScan(plan, (ExprContext *) NULL, plan); /* - * For all sublink types except EXPR_SUBLINK, the result is boolean - * as are the results of the combining operators. We combine results + * For all sublink types except EXPR_SUBLINK, the result is boolean as + * are the results of the combining operators. We combine results * within a tuple (if there are multiple columns) using OR semantics * if "useor" is true, AND semantics if not. We then combine results * across tuples (if the subplan produces more than one) using OR * semantics for ANY_SUBLINK or AND semantics for ALL_SUBLINK. * (MULTIEXPR_SUBLINK doesn't allow multiple tuples from the subplan.) * NULL results from the combining operators are handled according to - * the usual SQL semantics for OR and AND. The result for no input + * the usual SQL semantics for OR and AND. The result for no input * tuples is FALSE for ANY_SUBLINK, TRUE for ALL_SUBLINK, NULL for * MULTIEXPR_SUBLINK. * * For EXPR_SUBLINK we require the subplan to produce no more than one - * tuple, else an error is raised. If zero tuples are produced, we + * tuple, else an error is raised. If zero tuples are produced, we * return NULL. Assuming we get a tuple, we just return its first * column (there can be only one non-junk column in this case). */ @@ -106,13 +106,14 @@ ExecSubPlan(SubPlan *node, List *pvar, ExprContext *econtext, bool *isNull) if (found) elog(ERROR, "More than one tuple returned by a subselect used as an expression."); found = true; + /* - * We need to copy the subplan's tuple in case the result is of - * pass-by-ref type --- our return value will point into this - * copied tuple! Can't use the subplan's instance of the tuple - * since it won't still be valid after next ExecProcNode() call. - * node->curTuple keeps track of the copied tuple for eventual - * freeing. + * We need to copy the subplan's tuple in case the result is + * of pass-by-ref type --- our return value will point into + * this copied tuple! Can't use the subplan's instance of the + * tuple since it won't still be valid after next + * ExecProcNode() call. node->curTuple keeps track of the + * copied tuple for eventual freeing. */ tup = heap_copytuple(tup); if (node->curTuple) @@ -129,7 +130,8 @@ ExecSubPlan(SubPlan *node, List *pvar, ExprContext *econtext, bool *isNull) found = true; - /* For ALL, ANY, and MULTIEXPR sublinks, iterate over combining + /* + * For ALL, ANY, and MULTIEXPR sublinks, iterate over combining * operators for columns of tuple. */ foreach(lst, sublink->oper) @@ -140,14 +142,14 @@ ExecSubPlan(SubPlan *node, List *pvar, ExprContext *econtext, bool *isNull) bool expnull; /* - * The righthand side of the expression should be either a Const - * or a function call or RelabelType node taking a Const as arg - * (these nodes represent run-time type coercions inserted by - * the parser to get to the input type needed by the operator). - * Find the Const node and insert the actual righthand-side value - * into it. + * The righthand side of the expression should be either a + * Const or a function call or RelabelType node taking a Const + * as arg (these nodes represent run-time type coercions + * inserted by the parser to get to the input type needed by + * the operator). Find the Const node and insert the actual + * righthand-side value into it. */ - if (! IsA(con, Const)) + if (!IsA(con, Const)) { switch (con->type) { @@ -161,16 +163,18 @@ ExecSubPlan(SubPlan *node, List *pvar, ExprContext *econtext, bool *isNull) /* will fail below */ break; } - if (! IsA(con, Const)) + if (!IsA(con, Const)) elog(ERROR, "ExecSubPlan: failed to find placeholder for subplan result"); } con->constvalue = heap_getattr(tup, col, tdesc, &(con->constisnull)); + /* * Now we can eval the combining operator for this column. */ expresult = ExecEvalExpr((Node *) expr, econtext, &expnull, (bool *) NULL); + /* * Combine the result into the row result as appropriate. */ @@ -240,14 +244,16 @@ ExecSubPlan(SubPlan *node, List *pvar, ExprContext *econtext, bool *isNull) if (!found) { - /* deal with empty subplan result. result/isNull were previously + + /* + * deal with empty subplan result. result/isNull were previously * initialized correctly for all sublink types except EXPR and * MULTIEXPR; for those, return NULL. */ if (subLinkType == EXPR_SUBLINK || subLinkType == MULTIEXPR_SUBLINK) { - result = (Datum) false; - *isNull = true; + result = (Datum) false; + *isNull = true; } } @@ -354,9 +360,9 @@ ExecSetParamPlan(SubPlan *node) /* * We need to copy the subplan's tuple in case any of the params - * are pass-by-ref type --- the pointers stored in the param structs - * will point at this copied tuple! node->curTuple keeps track - * of the copied tuple for eventual freeing. + * are pass-by-ref type --- the pointers stored in the param + * structs will point at this copied tuple! node->curTuple keeps + * track of the copied tuple for eventual freeing. */ tup = heap_copytuple(tup); if (node->curTuple) diff --git a/src/backend/executor/nodeTidscan.c b/src/backend/executor/nodeTidscan.c index 7d9c6748637..31cdc205235 100644 --- a/src/backend/executor/nodeTidscan.c +++ b/src/backend/executor/nodeTidscan.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/nodeTidscan.c,v 1.5 2000/04/07 00:30:41 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/nodeTidscan.c,v 1.6 2000/04/12 17:15:10 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -32,21 +32,21 @@ #include "access/heapam.h" #include "parser/parsetree.h" -static int TidListCreate(List *, ExprContext *, ItemPointer *); +static int TidListCreate(List *, ExprContext *, ItemPointer *); static TupleTableSlot *TidNext(TidScan *node); static int TidListCreate(List *evalList, ExprContext *econtext, ItemPointer *tidList) { - List *lst; - ItemPointer itemptr; + List *lst; + ItemPointer itemptr; bool isNull; - int numTids = 0; + int numTids = 0; - foreach (lst, evalList) + foreach(lst, evalList) { - itemptr = (ItemPointer)ExecEvalExpr(lfirst(lst), econtext, - &isNull, (bool *)0); + itemptr = (ItemPointer) ExecEvalExpr(lfirst(lst), econtext, + &isNull, (bool *) 0); if (itemptr && ItemPointerIsValid(itemptr)) { tidList[numTids] = itemptr; @@ -67,20 +67,21 @@ TidListCreate(List *evalList, ExprContext *econtext, ItemPointer *tidList) static TupleTableSlot * TidNext(TidScan *node) { - EState *estate; + EState *estate; CommonScanState *scanstate; - TidScanState *tidstate; - ScanDirection direction; + TidScanState *tidstate; + ScanDirection direction; Snapshot snapshot; Relation heapRelation; HeapTuple tuple; - TupleTableSlot *slot; + TupleTableSlot *slot; Buffer buffer = InvalidBuffer; - int numTids; + int numTids; bool bBackward; - int tidNumber; - ItemPointer *tidList, itemptr; + int tidNumber; + ItemPointer *tidList, + itemptr; /* ---------------- * extract necessary information from tid scan node @@ -108,7 +109,7 @@ TidNext(TidScan *node) ExecClearTuple(slot); if (estate->es_evTupleNull[node->scan.scanrelid - 1]) return slot; /* return empty slot */ - + /* probably ought to use ExecStoreTuple here... */ slot->val = estate->es_evTuple[node->scan.scanrelid - 1]; slot->ttc_shouldFree = false; @@ -159,7 +160,7 @@ TidNext(TidScan *node) if (tuple->t_data != NULL) { bool prev_matches = false; - int prev_tid; + int prev_tid; /* ---------------- * store the scanned tuple in the scan tuple slot of @@ -169,23 +170,23 @@ TidNext(TidScan *node) * were not created with palloc() and so should not be pfree()'d. * ---------------- */ - ExecStoreTuple(tuple, /* tuple to store */ - slot, /* slot to store in */ - buffer, /* buffer associated with tuple */ - false); /* don't pfree */ + ExecStoreTuple(tuple, /* tuple to store */ + slot,/* slot to store in */ + buffer, /* buffer associated with tuple */ + false); /* don't pfree */ /* - * At this point we have an extra pin on the buffer, - * because ExecStoreTuple incremented the pin count. - * Drop our local pin. - */ - ReleaseBuffer(buffer); + * At this point we have an extra pin on the buffer, because + * ExecStoreTuple incremented the pin count. Drop our local + * pin. + */ + ReleaseBuffer(buffer); + /* - * We must check to see if the current tuple would have - * been matched by an earlier tid, so we don't double - * report it. We do this by passing the tuple through - * ExecQual and look for failure with all previous - * qualifications. + * We must check to see if the current tuple would have been + * matched by an earlier tid, so we don't double report it. We + * do this by passing the tuple through ExecQual and look for + * failure with all previous qualifications. */ for (prev_tid = 0; prev_tid < tidstate->tss_TidPtr; prev_tid++) @@ -209,7 +210,7 @@ TidNext(TidScan *node) else tidstate->tss_TidPtr++; if (slot_is_valid) - return slot; + return slot; } /* ---------------- * if we get here it means the tid scan failed so we @@ -255,9 +256,9 @@ ExecTidScan(TidScan *node) void ExecTidReScan(TidScan *node, ExprContext *exprCtxt, Plan *parent) { - EState *estate; - TidScanState *tidstate; - ItemPointer *tidList; + EState *estate; + TidScanState *tidstate; + ItemPointer *tidList; tidstate = node->tidstate; estate = node->scan.plan.state; @@ -278,7 +279,7 @@ ExecTidReScan(TidScan *node, ExprContext *exprCtxt, Plan *parent) } tidstate->tss_NumTids = TidListCreate(node->tideval, - node->scan.scanstate->cstate.cs_ExprContext, + node->scan.scanstate->cstate.cs_ExprContext, tidList); /* ---------------- @@ -299,7 +300,7 @@ void ExecEndTidScan(TidScan *node) { CommonScanState *scanstate; - TidScanState *tidstate; + TidScanState *tidstate; scanstate = node->scan.scanstate; tidstate = node->tidstate; @@ -385,18 +386,18 @@ ExecTidRestrPos(TidScan *node) bool ExecInitTidScan(TidScan *node, EState *estate, Plan *parent) { - TidScanState *tidstate; + TidScanState *tidstate; CommonScanState *scanstate; - ItemPointer *tidList; - int numTids; - int tidPtr; - List *rangeTable; - RangeTblEntry *rtentry; - Oid relid; - Oid reloid; + ItemPointer *tidList; + int numTids; + int tidPtr; + List *rangeTable; + RangeTblEntry *rtentry; + Oid relid; + Oid reloid; Relation currentRelation; - int baseid; + int baseid; List *execParam = NULL; @@ -473,7 +474,7 @@ ExecInitTidScan(TidScan *node, EState *estate, Plan *parent) * get the tid node information * ---------------- */ - tidList = (ItemPointer *)palloc(length(node->tideval) * sizeof(ItemPointer)); + tidList = (ItemPointer *) palloc(length(node->tideval) * sizeof(ItemPointer)); numTids = 0; if (!node->needRescan) numTids = TidListCreate(node->tideval, scanstate->cstate.cs_ExprContext, tidList); @@ -502,8 +503,8 @@ ExecInitTidScan(TidScan *node, EState *estate, Plan *parent) reloid = rtentry->relid; currentRelation = heap_open(reloid, AccessShareLock); - if (currentRelation == NULL) - elog(ERROR, "ExecInitTidScan heap_open failed."); + if (currentRelation == NULL) + elog(ERROR, "ExecInitTidScan heap_open failed."); scanstate->css_currentRelation = currentRelation; scanstate->css_currentScanDesc = 0; diff --git a/src/backend/executor/nodeUnique.c b/src/backend/executor/nodeUnique.c index f9f1fe81ab3..8c02126ebfb 100644 --- a/src/backend/executor/nodeUnique.c +++ b/src/backend/executor/nodeUnique.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/nodeUnique.c,v 1.27 2000/01/27 18:11:27 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/nodeUnique.c,v 1.28 2000/04/12 17:15:10 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -55,7 +55,7 @@ ExecUnique(Unique *node) uniquestate = node->uniquestate; outerPlan = outerPlan((Plan *) node); resultTupleSlot = uniquestate->cstate.cs_ResultTupleSlot; - tupDesc = ExecGetResultType(& uniquestate->cstate); + tupDesc = ExecGetResultType(&uniquestate->cstate); /* ---------------- * now loop, returning only non-duplicate tuples. @@ -86,16 +86,16 @@ ExecUnique(Unique *node) * another new tuple from the subplan. * ---------------- */ - if (! execTuplesMatch(slot->val, uniquestate->priorTuple, - tupDesc, - node->numCols, node->uniqColIdx, - uniquestate->eqfunctions)) + if (!execTuplesMatch(slot->val, uniquestate->priorTuple, + tupDesc, + node->numCols, node->uniqColIdx, + uniquestate->eqfunctions)) break; } /* ---------------- * We have a new tuple different from the previous saved tuple (if any). - * Save it and return it. Note that we make two copies of the tuple: + * Save it and return it. Note that we make two copies of the tuple: * one to keep for our own future comparisons, and one to return to the * caller. We need to copy the tuple returned by the subplan to avoid * holding buffer refcounts, and we need our own copy because the caller @@ -151,14 +151,14 @@ ExecInitUnique(Unique *node, EState *estate, Plan *parent) * they never call ExecQual or ExecTargetList. * ---------------- */ - ExecAssignNodeBaseInfo(estate, & uniquestate->cstate, parent); + ExecAssignNodeBaseInfo(estate, &uniquestate->cstate, parent); #define UNIQUE_NSLOTS 1 /* ------------ * Tuple table initialization * ------------ */ - ExecInitResultTupleSlot(estate, & uniquestate->cstate); + ExecInitResultTupleSlot(estate, &uniquestate->cstate); /* ---------------- * then initialize outer plan @@ -172,14 +172,14 @@ ExecInitUnique(Unique *node, EState *estate, Plan *parent) * projection info for this node appropriately * ---------------- */ - ExecAssignResultTypeFromOuterPlan((Plan *) node, & uniquestate->cstate); + ExecAssignResultTypeFromOuterPlan((Plan *) node, &uniquestate->cstate); uniquestate->cstate.cs_ProjInfo = NULL; /* * Precompute fmgr lookup data for inner loop */ uniquestate->eqfunctions = - execTuplesMatchPrepare(ExecGetResultType(& uniquestate->cstate), + execTuplesMatchPrepare(ExecGetResultType(&uniquestate->cstate), node->numCols, node->uniqColIdx); diff --git a/src/backend/lib/dllist.c b/src/backend/lib/dllist.c index 41663b40c1d..5711f70b690 100644 --- a/src/backend/lib/dllist.c +++ b/src/backend/lib/dllist.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/lib/dllist.c,v 1.16 2000/01/26 05:56:26 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/lib/dllist.c,v 1.17 2000/04/12 17:15:10 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -128,14 +128,16 @@ DLRemove(Dlelem *e) if (e->dle_prev) e->dle_prev->dle_next = e->dle_next; - else /* must be the head element */ + else +/* must be the head element */ { Assert(e == l->dll_head); l->dll_head = e->dle_next; } if (e->dle_next) e->dle_next->dle_prev = e->dle_prev; - else /* must be the tail element */ + else +/* must be the tail element */ { Assert(e == l->dll_tail); l->dll_tail = e->dle_prev; @@ -236,7 +238,8 @@ DLMoveToFront(Dlelem *e) if (e->dle_next) e->dle_next->dle_prev = e->dle_prev; - else /* must be the tail element */ + else +/* must be the tail element */ { Assert(e == l->dll_tail); l->dll_tail = e->dle_prev; diff --git a/src/backend/lib/stringinfo.c b/src/backend/lib/stringinfo.c index 9bfa42554ae..4f2df746843 100644 --- a/src/backend/lib/stringinfo.c +++ b/src/backend/lib/stringinfo.c @@ -9,7 +9,7 @@ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: stringinfo.c,v 1.24 2000/01/26 05:56:26 momjian Exp $ + * $Id: stringinfo.c,v 1.25 2000/04/12 17:15:11 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -85,7 +85,7 @@ enlargeStringInfo(StringInfo str, int needed) str->data = (char *) repalloc(str->data, newlen); if (str->data == NULL) elog(ERROR, - "enlargeStringInfo: Out of memory (%d bytes requested)", newlen); + "enlargeStringInfo: Out of memory (%d bytes requested)", newlen); str->maxlen = newlen; } @@ -122,12 +122,13 @@ appendStringInfo(StringInfo str, const char *fmt,...) nprinted = vsnprintf(str->data + str->len, avail, fmt, args); va_end(args); + /* * Note: some versions of vsnprintf return the number of chars - * actually stored, but at least one returns -1 on failure. - * Be conservative about believing whether the print worked. + * actually stored, but at least one returns -1 on failure. Be + * conservative about believing whether the print worked. */ - if (nprinted >= 0 && nprinted < avail-1) + if (nprinted >= 0 && nprinted < avail - 1) { /* Success. Note nprinted does not include trailing null. */ str->len += nprinted; diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c index 0b62b29c797..890be537c2e 100644 --- a/src/backend/libpq/auth.c +++ b/src/backend/libpq/auth.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/libpq/auth.c,v 1.43 2000/01/26 05:56:28 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/libpq/auth.c,v 1.44 2000/04/12 17:15:13 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -48,7 +48,7 @@ static int pg_passwordv0_recvauth(void *arg, PacketLen len, void *pkt); static int checkPassword(Port *port, char *user, char *password); static int old_be_recvauth(Port *port); static int map_old_to_new(Port *port, UserAuth old, int status); -static void auth_failed(Port *port); +static void auth_failed(Port *port); #ifdef KRB4 @@ -130,7 +130,7 @@ static int pg_krb4_recvauth(Port *port) { snprintf(PQerrormsg, PQERRORMSG_LENGTH, - "pg_krb4_recvauth: Kerberos not implemented on this server.\n"); + "pg_krb4_recvauth: Kerberos not implemented on this server.\n"); fputs(PQerrormsg, stderr); pqdebug("%s", PQerrormsg); @@ -455,7 +455,7 @@ be_recvauth(Port *port) * an error message into the postmaster logfile if it failed. */ - if (hba_getauthmethod(port) != STATUS_OK) + if (hba_getauthmethod(port) != STATUS_OK) PacketSendError(&port->pktInfo, "Missing or erroneous pg_hba.conf file, see postmaster log for details"); @@ -472,6 +472,7 @@ be_recvauth(Port *port) AuthRequest areq = AUTH_REQ_OK; PacketDoneProc auth_handler = NULL; + switch (port->auth_method) { case uaReject: diff --git a/src/backend/libpq/be-dumpdata.c b/src/backend/libpq/be-dumpdata.c index 296527337b4..fcc63e1e2a0 100644 --- a/src/backend/libpq/be-dumpdata.c +++ b/src/backend/libpq/be-dumpdata.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: be-dumpdata.c,v 1.32 2000/01/26 05:56:28 momjian Exp $ + * $Id: be-dumpdata.c,v 1.33 2000/04/12 17:15:14 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -184,7 +184,7 @@ be_typeinit(PortalEntry *entry, for (i = 0; i < natts; ++i) { strncpy(group->types[i].name, - NameStr(attrs[i]->attname), NAMEDATALEN); + NameStr(attrs[i]->attname), NAMEDATALEN); group->types[i].typid = attrs[i]->atttypid; group->types[i].typlen = attrs[i]->attlen; } diff --git a/src/backend/libpq/be-fsstubs.c b/src/backend/libpq/be-fsstubs.c index c97bf0d0647..1ac73fa0ea4 100644 --- a/src/backend/libpq/be-fsstubs.c +++ b/src/backend/libpq/be-fsstubs.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/libpq/be-fsstubs.c,v 1.43 2000/01/26 05:56:28 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/libpq/be-fsstubs.c,v 1.44 2000/04/12 17:15:14 momjian Exp $ * * NOTES * This should be moved to a more appropriate place. It is here @@ -18,7 +18,7 @@ * * These functions operate in a private GlobalMemoryContext, which means * that large object descriptors hang around until we destroy the context. - * That happens in lo_commit(). It'd be possible to prolong the lifetime + * That happens in lo_commit(). It'd be possible to prolong the lifetime * of the context so that LO FDs are good across transactions (for example, * we could release the context only if we see that no FDs remain open). * But we'd need additional state in order to do the right thing at the @@ -259,9 +259,9 @@ lo_tell(int fd) } /* - * We assume we do not need to switch contexts for inv_tell. - * That is true for now, but is probably more than this module - * ought to assume... + * We assume we do not need to switch contexts for inv_tell. That is + * true for now, but is probably more than this module ought to + * assume... */ return inv_tell(cookies[fd]); } @@ -269,10 +269,11 @@ lo_tell(int fd) int lo_unlink(Oid lobjId) { + /* - * inv_drop does not need a context switch, indeed it doesn't - * touch any LO-specific data structures at all. (Again, that's - * probably more than this module ought to be assuming.) + * inv_drop does not need a context switch, indeed it doesn't touch + * any LO-specific data structures at all. (Again, that's probably + * more than this module ought to be assuming.) * * XXX there ought to be some code to clean up any open LOs that * reference the specified relation... as is, they remain "open". @@ -417,9 +418,9 @@ lo_export(Oid lobjId, text *filename) /* * open the file to be written to * - * Note: we reduce backend's normal 077 umask to the slightly - * friendlier 022. This code used to drop it all the way to 0, - * but creating world-writable export files doesn't seem wise. + * Note: we reduce backend's normal 077 umask to the slightly friendlier + * 022. This code used to drop it all the way to 0, but creating + * world-writable export files doesn't seem wise. */ nbytes = VARSIZE(filename) - VARHDRSZ + 1; if (nbytes > FNAME_BUFSIZE) @@ -470,8 +471,9 @@ lo_commit(bool isCommit) currentContext = MemoryContextSwitchTo((MemoryContext) fscxt); - /* Clean out still-open index scans (not necessary if aborting) - * and clear cookies array so that LO fds are no longer good. + /* + * Clean out still-open index scans (not necessary if aborting) and + * clear cookies array so that LO fds are no longer good. */ for (i = 0; i < MAX_LOBJ_FDS; i++) { diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c index 799693ca51d..2bdf5fbf4b4 100644 --- a/src/backend/libpq/hba.c +++ b/src/backend/libpq/hba.c @@ -5,7 +5,7 @@ * wherein you authenticate a user by seeing what IP address the system * says he comes from and possibly using ident). * - * $Id: hba.c,v 1.50 2000/03/17 02:36:08 tgl Exp $ + * $Id: hba.c,v 1.51 2000/04/12 17:15:14 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -209,31 +209,32 @@ process_hba_record(FILE *file, hbaPort *port, bool *matches_p, bool *error_p) */ if ((strcmp(db, port->database) != 0 && strcmp(db, "all") != 0 && - (strcmp(db, "sameuser") != 0 || strcmp(port->database, port->user) != 0)) || - port->raddr.sa.sa_family != AF_UNIX) + (strcmp(db, "sameuser") != 0 || strcmp(port->database, port->user) != 0)) || + port->raddr.sa.sa_family != AF_UNIX) return; } else if (strcmp(buf, "host") == 0 || strcmp(buf, "hostssl") == 0) { struct in_addr file_ip_addr, mask; - bool discard = 0; /* Discard this entry */ + bool discard = 0;/* Discard this entry */ #ifdef USE_SSL /* If SSL, then check that we are on SSL */ - if (strcmp(buf, "hostssl") == 0) { - if (!port->ssl) - discard = 1; - - /* Placeholder to require specific SSL level, perhaps? */ - /* Or a client certificate */ - - /* Since we were on SSL, proceed as with normal 'host' mode */ + if (strcmp(buf, "hostssl") == 0) + { + if (!port->ssl) + discard = 1; + + /* Placeholder to require specific SSL level, perhaps? */ + /* Or a client certificate */ + + /* Since we were on SSL, proceed as with normal 'host' mode */ } #else /* If not SSL, we don't support this */ - if (strcmp(buf,"hostssl") == 0) - goto syntax; + if (strcmp(buf, "hostssl") == 0) + goto syntax; #endif /* Get the database. */ @@ -286,7 +287,7 @@ process_hba_record(FILE *file, hbaPort *port, bool *matches_p, bool *error_p) * "out of sync" with the file. */ if (discard) - return; + return; /* * If this record isn't for our database, or this is the wrong @@ -294,8 +295,8 @@ process_hba_record(FILE *file, hbaPort *port, bool *matches_p, bool *error_p) */ if ((strcmp(db, port->database) != 0 && strcmp(db, "all") != 0 && - (strcmp(db, "sameuser") != 0 || strcmp(port->database, port->user) != 0)) || - port->raddr.sa.sa_family != AF_INET || + (strcmp(db, "sameuser") != 0 || strcmp(port->database, port->user) != 0)) || + port->raddr.sa.sa_family != AF_INET || ((file_ip_addr.s_addr ^ port->raddr.in.sin_addr.s_addr) & mask.s_addr) != 0x0000) return; } @@ -353,7 +354,7 @@ process_open_config_file(FILE *file, hbaPort *port, bool *hba_ok_p) /* If no matching entry was found, synthesize 'reject' entry. */ if (!found_entry) - port->auth_method = uaReject; + port->auth_method = uaReject; *hba_ok_p = true; } diff --git a/src/backend/libpq/portalbuf.c b/src/backend/libpq/portalbuf.c index 44be2950611..3cab2e4a7df 100644 --- a/src/backend/libpq/portalbuf.c +++ b/src/backend/libpq/portalbuf.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/libpq/Attic/portalbuf.c,v 1.23 2000/03/17 02:36:08 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/libpq/Attic/portalbuf.c,v 1.24 2000/04/12 17:15:14 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -88,7 +88,7 @@ portals_realloc(size_t size) portals = newp; else libpq_raise(&PortalError, - vararg_format("Cannot alloc more memory in portals_realloc")); + vararg_format("Cannot alloc more memory in portals_realloc")); for (i = oldsize; i < (int) portals_array_size; i++) portals[i] = (PortalEntry *) NULL; @@ -461,7 +461,7 @@ pbuf_findGroup(PortalBuffer *portal, if (group == NULL) libpq_raise(&PortalError, - vararg_format("Group index %d out of bound.", group_index)); + vararg_format("Group index %d out of bound.", group_index)); return group; } @@ -484,7 +484,7 @@ pbuf_findFnumber(GroupBuffer *group, return i; libpq_raise(&PortalError, - vararg_format("Field-name %s does not exist.", field_name)); + vararg_format("Field-name %s does not exist.", field_name)); /* not reached, here to make compiler happy */ return 0; @@ -501,7 +501,7 @@ pbuf_checkFnumber(GroupBuffer *group, { if (field_number < 0 || field_number >= group->no_fields) libpq_raise(&PortalError, - vararg_format("Field number %d out of bound.", field_number)); + vararg_format("Field number %d out of bound.", field_number)); } /* -------------------------------- diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c index 3895ae546f0..61c9e97b392 100644 --- a/src/backend/libpq/pqcomm.c +++ b/src/backend/libpq/pqcomm.c @@ -29,7 +29,7 @@ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: pqcomm.c,v 1.87 2000/01/26 05:56:29 momjian Exp $ + * $Id: pqcomm.c,v 1.88 2000/04/12 17:15:14 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -75,7 +75,7 @@ #include "postgres.h" #include "libpq/libpq.h" -#include "utils/trace.h" /* needed for HAVE_FCNTL_SETLK */ +#include "utils/trace.h" /* needed for HAVE_FCNTL_SETLK */ #include "miscadmin.h" @@ -270,7 +270,7 @@ StreamServerPort(char *hostName, unsigned short portName, int *fdP) { snprintf(PQerrormsg, PQERRORMSG_LENGTH, "FATAL: StreamServerPort: bind() failed: %s\n" - "\tIs another postmaster already running on that port?\n", + "\tIs another postmaster already running on that port?\n", strerror(errno)); if (family == AF_UNIX) snprintf(PQerrormsg + strlen(PQerrormsg), @@ -438,15 +438,15 @@ pq_recvbuf(void) for (;;) { int r; - + #ifdef USE_SSL if (MyProcPort->ssl) - r = SSL_read(MyProcPort->ssl, PqRecvBuffer + PqRecvLength, - PQ_BUFFER_SIZE - PqRecvLength); + r = SSL_read(MyProcPort->ssl, PqRecvBuffer + PqRecvLength, + PQ_BUFFER_SIZE - PqRecvLength); else #endif - r = recv(MyProcPort->sock, PqRecvBuffer + PqRecvLength, - PQ_BUFFER_SIZE - PqRecvLength, 0); + r = recv(MyProcPort->sock, PqRecvBuffer + PqRecvLength, + PQ_BUFFER_SIZE - PqRecvLength, 0); if (r < 0) { @@ -561,9 +561,7 @@ pq_getstring(StringInfo s) /* Read until we get the terminating '\0' */ while ((c = pq_getbyte()) != EOF && c != '\0') - { appendStringInfoChar(s, c); - } if (c == EOF) return EOF; @@ -614,12 +612,13 @@ pq_flush(void) while (bufptr < bufend) { int r; + #ifdef USE_SSL if (MyProcPort->ssl) - r = SSL_write(MyProcPort->ssl, bufptr, bufend - bufptr); + r = SSL_write(MyProcPort->ssl, bufptr, bufend - bufptr); else #endif - r = send(MyProcPort->sock, bufptr, bufend - bufptr, 0); + r = send(MyProcPort->sock, bufptr, bufend - bufptr, 0); if (r <= 0) { diff --git a/src/backend/libpq/pqformat.c b/src/backend/libpq/pqformat.c index 9147039a008..7275893c5c0 100644 --- a/src/backend/libpq/pqformat.c +++ b/src/backend/libpq/pqformat.c @@ -16,7 +16,7 @@ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: pqformat.c,v 1.12 2000/01/26 05:56:29 momjian Exp $ + * $Id: pqformat.c,v 1.13 2000/04/12 17:15:14 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -156,6 +156,7 @@ void pq_sendstring(StringInfo buf, const char *str) { int slen = strlen(str); + #ifdef MULTIBYTE char *p; @@ -237,13 +238,15 @@ int pq_puttextmessage(char msgtype, const char *str) { int slen = strlen(str); + #ifdef MULTIBYTE char *p; p = (char *) pg_server_to_client((unsigned char *) str, slen); if (p != str) /* actual conversion has been done? */ { - int result = pq_putmessage(msgtype, p, strlen(p) + 1); + int result = pq_putmessage(msgtype, p, strlen(p) + 1); + pfree(p); return result; } @@ -308,8 +311,10 @@ int pq_getstr(StringInfo s) { int result; + #ifdef MULTIBYTE char *p; + #endif result = pq_getstring(s); diff --git a/src/backend/libpq/pqpacket.c b/src/backend/libpq/pqpacket.c index 21dd26ca178..defc57f69af 100644 --- a/src/backend/libpq/pqpacket.c +++ b/src/backend/libpq/pqpacket.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/libpq/Attic/pqpacket.c,v 1.25 2000/03/19 22:10:07 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/libpq/Attic/pqpacket.c,v 1.26 2000/04/12 17:15:14 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -54,17 +54,17 @@ int PacketReceiveFragment(Port *port) { int got; - Packet *pkt = &port->pktInfo; + Packet *pkt = &port->pktInfo; #ifdef USE_SSL - if (port->ssl) - got = SSL_read(port->ssl, pkt->ptr, pkt->nrtodo); + if (port->ssl) + got = SSL_read(port->ssl, pkt->ptr, pkt->nrtodo); else #endif - got = read(port->sock, pkt->ptr, pkt->nrtodo); + got = read(port->sock, pkt->ptr, pkt->nrtodo); if (got > 0) { - pkt->nrtodo -= got; + pkt->nrtodo -= got; pkt->ptr += got; /* See if we have got what we need for the packet length. */ @@ -143,14 +143,14 @@ int PacketSendFragment(Port *port) { int done; - Packet *pkt = &port->pktInfo; + Packet *pkt = &port->pktInfo; #ifdef USE_SSL - if (port->ssl) - done = SSL_write(port->ssl, pkt->ptr, pkt->nrtodo); + if (port->ssl) + done = SSL_write(port->ssl, pkt->ptr, pkt->nrtodo); else #endif - done = write(port->sock, pkt->ptr, pkt->nrtodo); + done = write(port->sock, pkt->ptr, pkt->nrtodo); if (done > 0) { diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 58774b153aa..e146661fb84 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.112 2000/04/08 00:21:15 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.113 2000/04/12 17:15:16 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -143,7 +143,7 @@ _copyResult(Result *from) */ if (from->plan.subPlan != NIL) newnode->plan.subPlan = nconc(newnode->plan.subPlan, - pull_subplans(newnode->resconstantqual)); + pull_subplans(newnode->resconstantqual)); return newnode; } @@ -259,25 +259,25 @@ _copyIndexScan(IndexScan *from) if (from->scan.plan.subPlan != NIL) { newnode->scan.plan.subPlan = nconc(newnode->scan.plan.subPlan, - pull_subplans((Node *) newnode->indxqual)); + pull_subplans((Node *) newnode->indxqual)); newnode->scan.plan.subPlan = nconc(newnode->scan.plan.subPlan, - pull_subplans((Node *) newnode->indxqualorig)); + pull_subplans((Node *) newnode->indxqualorig)); } return newnode; } /* ---------------- - * _copyTidScan + * _copyTidScan * ---------------- */ static TidScan * _copyTidScan(TidScan *from) { - TidScan *newnode = makeNode(TidScan); + TidScan *newnode = makeNode(TidScan); /* ---------------- - * copy node superclass fields + * copy node superclass fields * ---------------- */ CopyPlanFields((Plan *) from, (Plan *) newnode); @@ -292,7 +292,7 @@ _copyTidScan(TidScan *from) return newnode; } - + /* ---------------- * CopyJoinFields * @@ -375,7 +375,7 @@ _copyMergeJoin(MergeJoin *from) */ if (from->join.subPlan != NIL) newnode->join.subPlan = nconc(newnode->join.subPlan, - pull_subplans((Node *) newnode->mergeclauses)); + pull_subplans((Node *) newnode->mergeclauses)); return newnode; } @@ -408,7 +408,7 @@ _copyHashJoin(HashJoin *from) */ if (from->join.subPlan != NIL) newnode->join.subPlan = nconc(newnode->join.subPlan, - pull_subplans((Node *) newnode->hashclauses)); + pull_subplans((Node *) newnode->hashclauses)); return newnode; } @@ -871,7 +871,7 @@ _copyAggref(Aggref *from) newnode->usenulls = from->usenulls; newnode->aggstar = from->aggstar; newnode->aggdistinct = from->aggdistinct; - newnode->aggno = from->aggno; /* probably not needed */ + newnode->aggno = from->aggno; /* probably not needed */ return newnode; } @@ -905,7 +905,7 @@ _copySubLink(SubLink *from) static RelabelType * _copyRelabelType(RelabelType *from) { - RelabelType *newnode = makeNode(RelabelType); + RelabelType *newnode = makeNode(RelabelType); /* ---------------- * copy remainder of node @@ -1108,6 +1108,7 @@ _copyIndexOptInfo(IndexOptInfo *from) static void CopyPathFields(Path *from, Path *newnode) { + /* * Modify the next line, since it causes the copying to cycle (i.e. * the parent points right back here! -- JMH, 7/7/92. Old version: @@ -1166,13 +1167,13 @@ _copyIndexPath(IndexPath *from) } /* ---------------- - * _copyTidPath + * _copyTidPath * ---------------- */ static TidPath * _copyTidPath(TidPath *from) { - TidPath *newnode = makeNode(TidPath); + TidPath *newnode = makeNode(TidPath); /* ---------------- * copy the node superclass fields @@ -1189,6 +1190,7 @@ _copyTidPath(TidPath *from) return newnode; } + /* ---------------- * CopyJoinPathFields * @@ -1282,7 +1284,7 @@ _copyHashPath(HashPath *from) static PathKeyItem * _copyPathKeyItem(PathKeyItem *from) { - PathKeyItem *newnode = makeNode(PathKeyItem); + PathKeyItem *newnode = makeNode(PathKeyItem); /* ---------------- * copy remainder of node @@ -1497,8 +1499,8 @@ _copyQuery(Query *from) /* * We do not copy the planner internal fields: base_rel_list, - * join_rel_list, equi_key_list, query_pathkeys. - * Not entirely clear if this is right? + * join_rel_list, equi_key_list, query_pathkeys. Not entirely clear if + * this is right? */ return newnode; @@ -1507,7 +1509,7 @@ _copyQuery(Query *from) static ClosePortalStmt * _copyClosePortalStmt(ClosePortalStmt *from) { - ClosePortalStmt *newnode = makeNode(ClosePortalStmt); + ClosePortalStmt *newnode = makeNode(ClosePortalStmt); if (from->portalname) newnode->portalname = pstrdup(from->portalname); @@ -1518,7 +1520,7 @@ _copyClosePortalStmt(ClosePortalStmt *from) static TruncateStmt * _copyTruncateStmt(TruncateStmt *from) { - TruncateStmt *newnode = makeNode(TruncateStmt); + TruncateStmt *newnode = makeNode(TruncateStmt); newnode->relName = pstrdup(from->relName); @@ -1528,7 +1530,7 @@ _copyTruncateStmt(TruncateStmt *from) static NotifyStmt * _copyNotifyStmt(NotifyStmt *from) { - NotifyStmt *newnode = makeNode(NotifyStmt); + NotifyStmt *newnode = makeNode(NotifyStmt); if (from->relname) newnode->relname = pstrdup(from->relname); @@ -1539,7 +1541,7 @@ _copyNotifyStmt(NotifyStmt *from) static ListenStmt * _copyListenStmt(ListenStmt *from) { - ListenStmt *newnode = makeNode(ListenStmt); + ListenStmt *newnode = makeNode(ListenStmt); if (from->relname) newnode->relname = pstrdup(from->relname); @@ -1550,7 +1552,7 @@ _copyListenStmt(ListenStmt *from) static UnlistenStmt * _copyUnlistenStmt(UnlistenStmt *from) { - UnlistenStmt *newnode = makeNode(UnlistenStmt); + UnlistenStmt *newnode = makeNode(UnlistenStmt); if (from->relname) newnode->relname = pstrdup(from->relname); @@ -1561,7 +1563,7 @@ _copyUnlistenStmt(UnlistenStmt *from) static TransactionStmt * _copyTransactionStmt(TransactionStmt *from) { - TransactionStmt *newnode = makeNode(TransactionStmt); + TransactionStmt *newnode = makeNode(TransactionStmt); newnode->command = from->command; @@ -1571,7 +1573,7 @@ _copyTransactionStmt(TransactionStmt *from) static LoadStmt * _copyLoadStmt(LoadStmt *from) { - LoadStmt *newnode = makeNode(LoadStmt); + LoadStmt *newnode = makeNode(LoadStmt); if (from->filename) newnode->filename = pstrdup(from->filename); @@ -1582,7 +1584,7 @@ _copyLoadStmt(LoadStmt *from) static VariableSetStmt * _copyVariableSetStmt(VariableSetStmt *from) { - VariableSetStmt *newnode = makeNode(VariableSetStmt); + VariableSetStmt *newnode = makeNode(VariableSetStmt); if (from->name) newnode->name = pstrdup(from->name); @@ -1595,7 +1597,7 @@ _copyVariableSetStmt(VariableSetStmt *from) static VariableResetStmt * _copyVariableResetStmt(VariableResetStmt *from) { - VariableResetStmt *newnode = makeNode(VariableResetStmt); + VariableResetStmt *newnode = makeNode(VariableResetStmt); if (from->name) newnode->name = pstrdup(from->name); @@ -1606,7 +1608,7 @@ _copyVariableResetStmt(VariableResetStmt *from) static LockStmt * _copyLockStmt(LockStmt *from) { - LockStmt *newnode = makeNode(LockStmt); + LockStmt *newnode = makeNode(LockStmt); if (from->relname) newnode->relname = pstrdup(from->relname); diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 139822ffae9..ddb5c72391b 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.65 2000/03/22 22:08:32 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.66 2000/04/12 17:15:16 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -81,9 +81,11 @@ _equalFjoin(Fjoin *a, Fjoin *b) static bool _equalExpr(Expr *a, Expr *b) { - /* We do not examine typeOid, since the optimizer often doesn't - * bother to set it in created nodes, and it is logically a - * derivative of the oper field anyway. + + /* + * We do not examine typeOid, since the optimizer often doesn't bother + * to set it in created nodes, and it is logically a derivative of the + * oper field anyway. */ if (a->opType != b->opType) return false; @@ -134,7 +136,9 @@ _equalOper(Oper *a, Oper *b) return false; if (a->opresulttype != b->opresulttype) return false; - /* We do not examine opid, opsize, or op_fcache, since these are + + /* + * We do not examine opid, opsize, or op_fcache, since these are * logically derived from opno, and they may not be set yet depending * on how far along the node is in the parse/plan pipeline. * @@ -156,10 +160,11 @@ _equalConst(Const *a, Const *b) if (a->constbyval != b->constbyval) return false; /* XXX What about constisset and constiscast? */ + /* - * We treat all NULL constants of the same type as equal. - * Someday this might need to change? But datumIsEqual - * doesn't work on nulls, so... + * We treat all NULL constants of the same type as equal. Someday this + * might need to change? But datumIsEqual doesn't work on nulls, + * so... */ if (a->constisnull) return true; @@ -320,7 +325,9 @@ _equalArrayRef(ArrayRef *a, ArrayRef *b) static bool _equalRelOptInfo(RelOptInfo *a, RelOptInfo *b) { - /* We treat RelOptInfos as equal if they refer to the same base rels + + /* + * We treat RelOptInfos as equal if they refer to the same base rels * joined in the same order. Is this sufficient? */ return equali(a->relids, b->relids); @@ -329,8 +336,10 @@ _equalRelOptInfo(RelOptInfo *a, RelOptInfo *b) static bool _equalIndexOptInfo(IndexOptInfo *a, IndexOptInfo *b) { - /* We treat IndexOptInfos as equal if they refer to the same index. - * Is this sufficient? + + /* + * We treat IndexOptInfos as equal if they refer to the same index. Is + * this sufficient? */ if (a->indexoid != b->indexoid) return false; @@ -354,7 +363,9 @@ _equalPath(Path *a, Path *b) return false; if (!equal(a->parent, b->parent)) return false; - /* do not check path costs, since they may not be set yet, and being + + /* + * do not check path costs, since they may not be set yet, and being * float values there are roundoff error issues anyway... */ if (!equal(a->pathkeys, b->pathkeys)) @@ -375,8 +386,10 @@ _equalIndexPath(IndexPath *a, IndexPath *b) return false; if (!equali(a->joinrelids, b->joinrelids)) return false; - /* Skip 'rows' because of possibility of floating-point roundoff error. - * It should be derivable from the other fields anyway. + + /* + * Skip 'rows' because of possibility of floating-point roundoff + * error. It should be derivable from the other fields anyway. */ return true; } @@ -442,12 +455,13 @@ _equalHashPath(HashPath *a, HashPath *b) /* XXX This equality function is a quick hack, should be * fixed to compare all fields. * - * XXX Why is this even here? We don't have equal() funcs for - * any other kinds of Plan nodes... likely this is dead code... + * XXX Why is this even here? We don't have equal() funcs for + * any other kinds of Plan nodes... likely this is dead code... */ static bool _equalIndexScan(IndexScan *a, IndexScan *b) { + /* * if(a->scan.plan.cost != b->scan.plan.cost) return(false); */ @@ -642,9 +656,9 @@ _equalQuery(Query *a, Query *b) /* * We do not check the internal-to-the-planner fields: base_rel_list, - * join_rel_list, equi_key_list, query_pathkeys. - * They might not be set yet, and in any case they should be derivable - * from the other fields. + * join_rel_list, equi_key_list, query_pathkeys. They might not be set + * yet, and in any case they should be derivable from the other + * fields. */ return true; } @@ -882,7 +896,8 @@ equal(void *a, void *b) List *lb = (List *) b; List *l; - /* Try to reject by length check before we grovel through + /* + * Try to reject by length check before we grovel through * all the elements... */ if (length(la) != length(lb)) diff --git a/src/backend/nodes/freefuncs.c b/src/backend/nodes/freefuncs.c index 96ce56c94c4..c0d07a05dba 100644 --- a/src/backend/nodes/freefuncs.c +++ b/src/backend/nodes/freefuncs.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/Attic/freefuncs.c,v 1.39 2000/03/14 23:06:28 thomas Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/Attic/freefuncs.c,v 1.40 2000/04/12 17:15:16 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -746,7 +746,9 @@ _freeRelOptInfo(RelOptInfo *node) freeObject(node->targetlist); freeObject(node->pathlist); - /* XXX is this right? cheapest-path fields will typically be pointers + + /* + * XXX is this right? cheapest-path fields will typically be pointers * into pathlist, not separate structs... */ freeObject(node->cheapest_startup_path); @@ -870,7 +872,9 @@ FreeJoinPathFields(JoinPath *node) { freeObject(node->outerjoinpath); freeObject(node->innerjoinpath); - /* XXX probably wrong, since ordinarily a JoinPath would share its + + /* + * XXX probably wrong, since ordinarily a JoinPath would share its * restrictinfo list with other paths made for the same join? */ freeObject(node->joinrestrictinfo); @@ -970,7 +974,9 @@ _freeRestrictInfo(RestrictInfo *node) * ---------------- */ freeObject(node->clause); - /* this is certainly wrong? IndexOptInfos don't belong to + + /* + * this is certainly wrong? IndexOptInfos don't belong to * RestrictInfo... */ freeObject(node->subclauseindices); @@ -1131,8 +1137,8 @@ _freeValue(Value *node) { switch (node->type) { - case T_Float: - case T_String: + case T_Float: + case T_String: pfree(node->val.str); break; default: diff --git a/src/backend/nodes/list.c b/src/backend/nodes/list.c index a47851f2420..66d69199beb 100644 --- a/src/backend/nodes/list.c +++ b/src/backend/nodes/list.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/list.c,v 1.30 2000/02/21 18:47:00 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/list.c,v 1.31 2000/04/12 17:15:16 momjian Exp $ * * NOTES * XXX a few of the following functions are duplicated to handle @@ -251,9 +251,9 @@ length(List *l) * freeList * * Free the List nodes of a list - * The pointed-to nodes, if any, are NOT freed. - * This works for integer lists too. - * + * The pointed-to nodes, if any, are NOT freed. + * This works for integer lists too. + * */ void freeList(List *list) @@ -314,7 +314,7 @@ LispUnion(List *l1, List *l2) foreach(i, l2) { - if (! member(lfirst(i), retval)) + if (!member(lfirst(i), retval)) retval = lappend(retval, lfirst(i)); } return retval; @@ -328,7 +328,7 @@ LispUnioni(List *l1, List *l2) foreach(i, l2) { - if (! intMember(lfirsti(i), retval)) + if (!intMember(lfirsti(i), retval)) retval = lappendi(retval, lfirsti(i)); } return retval; @@ -459,7 +459,7 @@ intLispRemove(int elem, List *list) List * ltruncate(int n, List *list) { - List *ptr; + List *ptr; if (n <= 0) return NIL; /* truncate to zero length */ @@ -494,7 +494,7 @@ set_difference(List *l1, List *l2) foreach(i, l1) { - if (! member(lfirst(i), l2)) + if (!member(lfirst(i), l2)) result = lappend(result, lfirst(i)); } return result; @@ -516,7 +516,7 @@ set_differencei(List *l1, List *l2) foreach(i, l1) { - if (! intMember(lfirsti(i), l2)) + if (!intMember(lfirsti(i), l2)) result = lappendi(result, lfirsti(i)); } return result; diff --git a/src/backend/nodes/makefuncs.c b/src/backend/nodes/makefuncs.c index e42930ef87b..4bad2008d77 100644 --- a/src/backend/nodes/makefuncs.c +++ b/src/backend/nodes/makefuncs.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/makefuncs.c,v 1.20 2000/02/15 03:37:09 thomas Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/makefuncs.c,v 1.21 2000/04/12 17:15:16 momjian Exp $ * * NOTES * Creator functions in POSTGRES 4.2 are generated automatically. Most of @@ -62,11 +62,13 @@ makeVar(Index varno, var->vartype = vartype; var->vartypmod = vartypmod; var->varlevelsup = varlevelsup; + /* - * Since few if any routines ever create Var nodes with varnoold/varoattno - * different from varno/varattno, we don't provide separate arguments - * for them, but just initialize them to the given varno/varattno. - * This reduces code clutter and chance of error for most callers. + * Since few if any routines ever create Var nodes with + * varnoold/varoattno different from varno/varattno, we don't provide + * separate arguments for them, but just initialize them to the given + * varno/varattno. This reduces code clutter and chance of error for + * most callers. */ var->varnoold = varno; var->varoattno = varattno; @@ -107,7 +109,9 @@ makeResdom(AttrNumber resno, resdom->restype = restype; resdom->restypmod = restypmod; resdom->resname = resname; - /* For historical reasons, ressortgroupref defaults to 0 while + + /* + * For historical reasons, ressortgroupref defaults to 0 while * reskey/reskeyop are passed in explicitly. This is pretty silly. */ resdom->ressortgroupref = 0; @@ -159,8 +163,3 @@ makeAttr(char *relname, char *attname) return a; } - - - - - diff --git a/src/backend/nodes/nodes.c b/src/backend/nodes/nodes.c index 3615a762a8a..0f0c417f68c 100644 --- a/src/backend/nodes/nodes.c +++ b/src/backend/nodes/nodes.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/nodes.c,v 1.12 2000/01/26 05:56:31 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/nodes.c,v 1.13 2000/04/12 17:15:16 momjian Exp $ * * HISTORY * Andrew Yu Oct 20, 1994 file creation @@ -33,7 +33,7 @@ newNode(Size size, NodeTag tag) { Node *newNode; - Assert(size >= sizeof(Node)); /* need the tag, at least */ + Assert(size >= sizeof(Node)); /* need the tag, at least */ newNode = (Node *) palloc(size); MemSet((char *) newNode, 0, size); diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index 489e4fbbf91..a870a9f5702 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * - * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.113 2000/03/24 02:58:25 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.114 2000/04/12 17:15:16 momjian Exp $ * * NOTES * Every (plan) node in POSTGRES has an associated "out" routine which @@ -60,10 +60,11 @@ _outToken(StringInfo str, char *s) appendStringInfo(str, "<>"); return; } + /* * Look for characters or patterns that are treated specially by - * read.c (either in lsptok() or in nodeRead()), and therefore need - * a protective backslash. + * read.c (either in lsptok() or in nodeRead()), and therefore need a + * protective backslash. */ /* These characters only need to be quoted at the start of the string */ if (*s == '<' || @@ -256,7 +257,7 @@ _outQuery(StringInfo str, Query *node) _outToken(str, node->into); appendStringInfo(str, - " :isPortal %s :isBinary %s :isTemp %s :unionall %s :distinctClause ", + " :isPortal %s :isBinary %s :isTemp %s :unionall %s :distinctClause ", node->isPortal ? "true" : "false", node->isBinary ? "true" : "false", node->isTemp ? "true" : "false", @@ -633,7 +634,7 @@ static void _outResdom(StringInfo str, Resdom *node) { appendStringInfo(str, - " RESDOM :resno %d :restype %u :restypmod %d :resname ", + " RESDOM :resno %d :restype %u :restypmod %d :resname ", node->resno, node->restype, node->restypmod); @@ -925,7 +926,7 @@ _outRelOptInfo(StringInfo str, RelOptInfo *node) _outIntList(str, node->relids); appendStringInfo(str, - " :rows %.0f :width %d :indexed %s :pages %ld :tuples %.0f :targetlist ", + " :rows %.0f :width %d :indexed %s :pages %ld :tuples %.0f :targetlist ", node->rows, node->width, node->indexed ? "true" : "false", @@ -983,7 +984,7 @@ _outRangeTblEntry(StringInfo str, RangeTblEntry *node) appendStringInfo(str, " :ref "); _outNode(str, node->ref); appendStringInfo(str, - " :relid %u :inh %s :inFromCl %s :inJoinSet %s :skipAcl %s", + " :relid %u :inh %s :inFromCl %s :inJoinSet %s :skipAcl %s", node->relid, node->inh ? "true" : "false", node->inFromCl ? "true" : "false", @@ -1004,7 +1005,7 @@ static void _outPath(StringInfo str, Path *node) { appendStringInfo(str, - " PATH :pathtype %d :startup_cost %.2f :total_cost %.2f :pathkeys ", + " PATH :pathtype %d :startup_cost %.2f :total_cost %.2f :pathkeys ", node->pathtype, node->startup_cost, node->total_cost); @@ -1282,12 +1283,14 @@ _outValue(StringInfo str, Value *value) { switch (value->type) { - case T_Integer: + case T_Integer: appendStringInfo(str, " %ld ", value->val.ival); break; case T_Float: - /* We assume the value is a valid numeric literal - * and so does not need quoting. + + /* + * We assume the value is a valid numeric literal and so does + * not need quoting. */ appendStringInfo(str, " %s ", value->val.str); break; diff --git a/src/backend/nodes/print.c b/src/backend/nodes/print.c index 248991c0928..8d3cd8d2a7b 100644 --- a/src/backend/nodes/print.c +++ b/src/backend/nodes/print.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/print.c,v 1.37 2000/02/15 20:49:12 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/print.c,v 1.38 2000/04/12 17:15:16 momjian Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -176,7 +176,7 @@ print_expr(Node *expr, List *rtable) rt = rt_fetch(var->varno, rtable); relname = rt->relname; if (rt->ref && rt->ref->relname) - relname = rt->ref->relname; /* table renamed */ + relname = rt->ref->relname; /* table renamed */ attname = get_attname(rt->relid, var->varattno); } break; @@ -221,7 +221,7 @@ print_pathkeys(List *pathkeys, List *rtable) printf("("); foreach(k, pathkey) { - PathKeyItem *item = lfirst(k); + PathKeyItem *item = lfirst(k); print_expr(item->key, rtable); if (lnext(k)) diff --git a/src/backend/nodes/read.c b/src/backend/nodes/read.c index 9f68f4d0e90..258bb7ed30b 100644 --- a/src/backend/nodes/read.c +++ b/src/backend/nodes/read.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/read.c,v 1.21 2000/02/21 18:47:00 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/read.c,v 1.22 2000/04/12 17:15:16 momjian Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -60,31 +60,31 @@ stringToNode(char *str) * (Pass length==NULL to set the string without reading its first token.) * * The rules for tokens are: - * * Whitespace (space, tab, newline) always separates tokens. - * * The characters '(', ')', '{', '}' form individual tokens even - * without any whitespace around them. - * * Otherwise, a token is all the characters up to the next whitespace - * or occurrence of one of the four special characters. - * * A backslash '\' can be used to quote whitespace or one of the four - * special characters, so that it is treated as a plain token character. - * Backslashes themselves must also be backslashed for consistency. - * Any other character can be, but need not be, backslashed as well. - * * If the resulting token is '<>' (with no backslash), it is returned - * as a non-NULL pointer to the token but with length == 0. Note that - * there is no other way to get a zero-length token. + * * Whitespace (space, tab, newline) always separates tokens. + * * The characters '(', ')', '{', '}' form individual tokens even + * without any whitespace around them. + * * Otherwise, a token is all the characters up to the next whitespace + * or occurrence of one of the four special characters. + * * A backslash '\' can be used to quote whitespace or one of the four + * special characters, so that it is treated as a plain token character. + * Backslashes themselves must also be backslashed for consistency. + * Any other character can be, but need not be, backslashed as well. + * * If the resulting token is '<>' (with no backslash), it is returned + * as a non-NULL pointer to the token but with length == 0. Note that + * there is no other way to get a zero-length token. * * Returns a pointer to the start of the next token, and the length of the - * token (including any embedded backslashes!) in *length. If there are + * token (including any embedded backslashes!) in *length. If there are * no more tokens, NULL and 0 are returned. * * NOTE: this routine doesn't remove backslashes; the caller must do so * if necessary (see "debackslash"). * * NOTE: prior to release 7.0, this routine also had a special case to treat - * a token starting with '"' as extending to the next '"'. This code was + * a token starting with '"' as extending to the next '"'. This code was * broken, however, since it would fail to cope with a string containing an * embedded '"'. I have therefore removed this special case, and instead - * introduced rules for using backslashes to quote characters. Higher-level + * introduced rules for using backslashes to quote characters. Higher-level * code should add backslashes to a string constant to ensure it is treated * as a single token. */ @@ -160,8 +160,8 @@ lsptok(char *string, int *length) char * debackslash(char *token, int length) { - char *result = palloc(length+1); - char *ptr = result; + char *result = palloc(length + 1); + char *ptr = result; while (length > 0) { @@ -208,22 +208,23 @@ nodeTokenType(char *token, int length) if ((numlen > 0 && isdigit(*numptr)) || (numlen > 1 && *numptr == '.' && isdigit(numptr[1]))) { + /* - * Yes. Figure out whether it is integral or float; - * this requires both a syntax check and a range check. - * strtol() can do both for us. - * We know the token will end at a character that strtol will + * Yes. Figure out whether it is integral or float; this requires + * both a syntax check and a range check. strtol() can do both for + * us. We know the token will end at a character that strtol will * stop at, so we do not need to modify the string. */ errno = 0; (void) strtol(token, &endptr, 10); - if (endptr != token+length || errno == ERANGE) + if (endptr != token + length || errno == ERANGE) return T_Float; return T_Integer; } + /* - * these three cases do not need length checks, since lsptok() - * will always treat them as single-byte tokens + * these three cases do not need length checks, since lsptok() will + * always treat them as single-byte tokens */ else if (*token == '(') retval = LEFT_PAREN; @@ -233,7 +234,7 @@ nodeTokenType(char *token, int length) retval = PLAN_SYM; else if (*token == '@' && length == 1) retval = AT_SYMBOL; - else if (*token == '\"' && length > 1 && token[length-1] == '\"') + else if (*token == '\"' && length > 1 && token[length - 1] == '\"') retval = T_String; else retval = ATOM_TOKEN; @@ -245,10 +246,10 @@ nodeTokenType(char *token, int length) * Slightly higher-level reader. * * This routine applies some semantic knowledge on top of the purely - * lexical tokenizer lsptok(). It can read + * lexical tokenizer lsptok(). It can read * * Value token nodes (integers, floats, or strings); - * * Plan nodes (via parsePlanString() from readfuncs.c); - * * Lists of the above. + * * Plan nodes (via parsePlanString() from readfuncs.c); + * * Lists of the above. * * Secrets: He assumes that lsptok already has the string (see above). * Any callers should set read_car_only to true. @@ -305,6 +306,7 @@ nodeRead(bool read_car_only) { /* must be "<>" */ this_value = NULL; + /* * It might be NULL but it is an atom! */ @@ -321,13 +323,17 @@ nodeRead(bool read_car_only) } break; case T_Integer: - /* we know that the token terminates on a char atol will stop at */ + + /* + * we know that the token terminates on a char atol will stop + * at + */ this_value = (Node *) makeInteger(atol(token)); make_dotted_pair_cell = true; break; case T_Float: { - char *fval = (char *) palloc(tok_len + 1); + char *fval = (char *) palloc(tok_len + 1); memcpy(fval, token, tok_len); fval[tok_len] = '\0'; @@ -337,7 +343,7 @@ nodeRead(bool read_car_only) break; case T_String: /* need to remove leading and trailing quotes, and backslashes */ - this_value = (Node *) makeString(debackslash(token+1, tok_len-2)); + this_value = (Node *) makeString(debackslash(token + 1, tok_len - 2)); make_dotted_pair_cell = true; break; default: diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c index 3a3059ef4e4..f16773574df 100644 --- a/src/backend/nodes/readfuncs.c +++ b/src/backend/nodes/readfuncs.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.87 2000/03/22 22:08:32 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.88 2000/04/12 17:15:17 momjian Exp $ * * NOTES * Most of the read functions for plan nodes are tested. (In fact, they @@ -538,7 +538,7 @@ _readIndexScan() static TidScan * _readTidScan() { - TidScan *local_node; + TidScan *local_node; char *token; int length; @@ -551,7 +551,7 @@ _readTidScan() local_node->needRescan = atoi(token); token = lsptok(NULL, &length); /* eat :tideval */ - local_node->tideval = nodeRead(true); /* now read it */ + local_node->tideval = nodeRead(true); /* now read it */ return local_node; } @@ -1308,17 +1308,17 @@ _readRelOptInfo() local_node->pathlist = nodeRead(true); /* now read it */ token = lsptok(NULL, &length); /* get :cheapest_startup_path */ - local_node->cheapest_startup_path = nodeRead(true); /* now read it */ + local_node->cheapest_startup_path = nodeRead(true); /* now read it */ token = lsptok(NULL, &length); /* get :cheapest_total_path */ - local_node->cheapest_total_path = nodeRead(true); /* now read it */ + local_node->cheapest_total_path = nodeRead(true); /* now read it */ token = lsptok(NULL, &length); /* eat :pruneable */ token = lsptok(NULL, &length); /* get :pruneable */ local_node->pruneable = (token[0] == 't') ? true : false; token = lsptok(NULL, &length); /* get :baserestrictinfo */ - local_node->baserestrictinfo = nodeRead(true); /* now read it */ + local_node->baserestrictinfo = nodeRead(true); /* now read it */ token = lsptok(NULL, &length); /* get :joininfo */ local_node->joininfo = nodeRead(true); /* now read it */ @@ -1365,7 +1365,7 @@ _readAttr() local_node->relname = debackslash(token, length); token = lsptok(NULL, &length); /* eat :attrs */ - local_node->attrs = nodeRead(true); /* now read it */ + local_node->attrs = nodeRead(true); /* now read it */ return local_node; } @@ -1526,7 +1526,7 @@ _readIndexPath() static TidPath * _readTidPath() { - TidPath *local_node; + TidPath *local_node; char *token; int length; @@ -1548,7 +1548,7 @@ _readTidPath() local_node->path.pathkeys = nodeRead(true); /* now read it */ token = lsptok(NULL, &length); /* get :tideval */ - local_node->tideval = nodeRead(true); /* now read it */ + local_node->tideval = nodeRead(true); /* now read it */ token = lsptok(NULL, &length); /* get :unjoined_relids */ local_node->unjoined_relids = toIntList(nodeRead(true)); @@ -1593,7 +1593,7 @@ _readNestPath() local_node->innerjoinpath = nodeRead(true); /* now read it */ token = lsptok(NULL, &length); /* get :joinrestrictinfo */ - local_node->joinrestrictinfo = nodeRead(true); /* now read it */ + local_node->joinrestrictinfo = nodeRead(true); /* now read it */ return local_node; } @@ -1629,13 +1629,13 @@ _readMergePath() local_node->jpath.path.pathkeys = nodeRead(true); /* now read it */ token = lsptok(NULL, &length); /* get :outerjoinpath */ - local_node->jpath.outerjoinpath = nodeRead(true); /* now read it */ + local_node->jpath.outerjoinpath = nodeRead(true); /* now read it */ token = lsptok(NULL, &length); /* get :innerjoinpath */ - local_node->jpath.innerjoinpath = nodeRead(true); /* now read it */ + local_node->jpath.innerjoinpath = nodeRead(true); /* now read it */ token = lsptok(NULL, &length); /* get :joinrestrictinfo */ - local_node->jpath.joinrestrictinfo = nodeRead(true); /* now read it */ + local_node->jpath.joinrestrictinfo = nodeRead(true); /* now read it */ token = lsptok(NULL, &length); /* get :path_mergeclauses */ local_node->path_mergeclauses = nodeRead(true); /* now read it */ @@ -1680,13 +1680,13 @@ _readHashPath() local_node->jpath.path.pathkeys = nodeRead(true); /* now read it */ token = lsptok(NULL, &length); /* get :outerjoinpath */ - local_node->jpath.outerjoinpath = nodeRead(true); /* now read it */ + local_node->jpath.outerjoinpath = nodeRead(true); /* now read it */ token = lsptok(NULL, &length); /* get :innerjoinpath */ - local_node->jpath.innerjoinpath = nodeRead(true); /* now read it */ + local_node->jpath.innerjoinpath = nodeRead(true); /* now read it */ token = lsptok(NULL, &length); /* get :joinrestrictinfo */ - local_node->jpath.joinrestrictinfo = nodeRead(true); /* now read it */ + local_node->jpath.joinrestrictinfo = nodeRead(true); /* now read it */ token = lsptok(NULL, &length); /* get :path_hashclauses */ local_node->path_hashclauses = nodeRead(true); /* now read it */ diff --git a/src/backend/optimizer/geqo/geqo_eval.c b/src/backend/optimizer/geqo/geqo_eval.c index 1c70e4bcd8d..6b04eb49ea6 100644 --- a/src/backend/optimizer/geqo/geqo_eval.c +++ b/src/backend/optimizer/geqo/geqo_eval.c @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: geqo_eval.c,v 1.48 2000/02/15 20:49:14 tgl Exp $ + * $Id: geqo_eval.c,v 1.49 2000/04/12 17:15:18 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -99,8 +99,8 @@ geqo_eval(Query *root, Gene *tour, int num_gene) /* * compute fitness * - * XXX geqo does not currently support optimization for partial - * result retrieval --- how to fix? + * XXX geqo does not currently support optimization for partial result + * retrieval --- how to fix? */ fitness = joinrel->cheapest_total_path->total_cost; @@ -135,7 +135,7 @@ gimme_tree(Query *root, Gene *tour, int rel_count, int num_gene, RelOptInfo *old /* tour[0] = 3; tour[1] = 1; tour[2] = 2 */ base_rel_index = (int) tour[rel_count]; - inner_rel = (RelOptInfo *) nth(base_rel_index-1, root->base_rel_list); + inner_rel = (RelOptInfo *) nth(base_rel_index - 1, root->base_rel_list); if (rel_count == 0) { /* processing first join with @@ -145,15 +145,15 @@ gimme_tree(Query *root, Gene *tour, int rel_count, int num_gene, RelOptInfo *old } else { /* tree main part */ - List *acceptable_rels = lcons(inner_rel, NIL); + List *acceptable_rels = lcons(inner_rel, NIL); new_rel = make_rels_by_clause_joins(root, old_rel, acceptable_rels); - if (! new_rel) + if (!new_rel) { new_rel = make_rels_by_clauseless_joins(root, old_rel, acceptable_rels); - if (! new_rel) + if (!new_rel) elog(ERROR, "gimme_tree: failed to construct join rel"); } diff --git a/src/backend/optimizer/path/_deadcode/predmig.c b/src/backend/optimizer/path/_deadcode/predmig.c index 377a836d9a1..434780d664c 100644 --- a/src/backend/optimizer/path/_deadcode/predmig.c +++ b/src/backend/optimizer/path/_deadcode/predmig.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/path/_deadcode/Attic/predmig.c,v 1.6 2000/01/26 05:56:36 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/path/_deadcode/Attic/predmig.c,v 1.7 2000/04/12 17:15:21 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -485,7 +485,7 @@ xfunc_form_groups(Query *queryInfo, Stream root, Stream bottom) } -/* ------------------- UTILITY FUNCTIONS ------------------------- */ +/* ------------------- UTILITY FUNCTIONS ------------------------- */ /* ** xfunc_free_stream diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 572ef00d2e8..a2e636395e2 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/path/allpaths.c,v 1.59 2000/02/15 20:49:16 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/path/allpaths.c,v 1.60 2000/04/12 17:15:19 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -24,8 +24,10 @@ #ifdef GEQO bool enable_geqo = true; + #else bool enable_geqo = false; + #endif int geqo_rels = GEQO_RELS; @@ -36,6 +38,7 @@ static RelOptInfo *make_one_rel_by_joins(Query *root, int levels_needed); #ifdef OPTIMIZER_DEBUG static void debug_print_rel(Query *root, RelOptInfo *rel); + #endif @@ -64,6 +67,7 @@ make_one_rel(Query *root) if (levels_needed == 1) { + /* * Single relation, no more processing is required. */ @@ -71,6 +75,7 @@ make_one_rel(Query *root) } else { + /* * Generate join tree. */ @@ -100,8 +105,8 @@ set_base_rel_pathlist(Query *root) /* * Generate paths and add them to the rel's pathlist. * - * Note: add_path() will discard any paths that are dominated - * by another available path, keeping only those paths that are + * Note: add_path() will discard any paths that are dominated by + * another available path, keeping only those paths that are * superior along at least one dimension of cost or sortedness. */ @@ -116,9 +121,10 @@ set_base_rel_pathlist(Query *root) rel->baserestrictinfo, rel->joininfo); - /* Note: create_or_index_paths depends on create_index_paths - * to have marked OR restriction clauses with relevant indices; - * this is why it doesn't need to be given the list of indices. + /* + * Note: create_or_index_paths depends on create_index_paths to + * have marked OR restriction clauses with relevant indices; this + * is why it doesn't need to be given the list of indices. */ create_or_index_paths(root, rel, rel->baserestrictinfo); @@ -153,11 +159,11 @@ make_one_rel_by_joins(Query *root, int levels_needed) return geqo(root); /* - * We employ a simple "dynamic programming" algorithm: we first - * find all ways to build joins of two base relations, then all ways - * to build joins of three base relations (from two-base-rel joins - * and other base rels), then four-base-rel joins, and so on until - * we have considered all ways to join all N relations into one rel. + * We employ a simple "dynamic programming" algorithm: we first find + * all ways to build joins of two base relations, then all ways to + * build joins of three base relations (from two-base-rel joins and + * other base rels), then four-base-rel joins, and so on until we have + * considered all ways to join all N relations into one rel. */ for (lev = 2; lev <= levels_needed; lev++) @@ -185,9 +191,10 @@ make_one_rel_by_joins(Query *root, int levels_needed) rel = (RelOptInfo *) lfirst(x); #ifdef NOT_USED + /* - * * for each expensive predicate in each path in each distinct - * rel, * consider doing pullup -- JMH + * * for each expensive predicate in each path in each + * distinct rel, * consider doing pullup -- JMH */ if (XfuncMode != XFUNC_NOPULL && XfuncMode != XFUNC_OFF) xfunc_trypullup(rel); diff --git a/src/backend/optimizer/path/clausesel.c b/src/backend/optimizer/path/clausesel.c index 985155edf92..d430059a1e0 100644 --- a/src/backend/optimizer/path/clausesel.c +++ b/src/backend/optimizer/path/clausesel.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/path/clausesel.c,v 1.33 2000/03/23 23:35:47 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/path/clausesel.c,v 1.34 2000/04/12 17:15:19 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -28,17 +28,18 @@ * Data structure for accumulating info about possible range-query * clause pairs in clauselist_selectivity. */ -typedef struct RangeQueryClause { - struct RangeQueryClause *next; /* next in linked list */ +typedef struct RangeQueryClause +{ + struct RangeQueryClause *next; /* next in linked list */ Node *var; /* The common variable of the clauses */ bool have_lobound; /* found a low-bound clause yet? */ bool have_hibound; /* found a high-bound clause yet? */ - Selectivity lobound; /* Selectivity of a var > something clause */ - Selectivity hibound; /* Selectivity of a var < something clause */ + Selectivity lobound; /* Selectivity of a var > something clause */ + Selectivity hibound; /* Selectivity of a var < something clause */ } RangeQueryClause; static void addRangeClause(RangeQueryClause **rqlist, Node *clause, - int flag, bool isLTsel, Selectivity s2); + int flag, bool isLTsel, Selectivity s2); /**************************************************************************** @@ -59,7 +60,7 @@ restrictlist_selectivity(Query *root, int varRelid) { List *clauselist = get_actual_clauses(restrictinfo_list); - Selectivity result; + Selectivity result; result = clauselist_selectivity(root, clauselist, varRelid); freeList(clauselist); @@ -75,7 +76,7 @@ restrictlist_selectivity(Query *root, * See clause_selectivity() for the meaning of the varRelid parameter. * * Our basic approach is to take the product of the selectivities of the - * subclauses. However, that's only right if the subclauses have independent + * subclauses. However, that's only right if the subclauses have independent * probabilities, and in reality they are often NOT independent. So, * we want to be smarter where we can. @@ -92,7 +93,7 @@ restrictlist_selectivity(Query *root, * see that hisel is the fraction of the range below the high bound, while * losel is the fraction above the low bound; so hisel can be interpreted * directly as a 0..1 value but we need to convert losel to 1-losel before - * interpreting it as a value. Then the available range is 1-losel to hisel.) + * interpreting it as a value. Then the available range is 1-losel to hisel.) * If the calculation yields zero or negative, however, we chicken out and * use the default interpretation; that probably means that one or both * selectivities is a default estimate rather than an actual range value. @@ -104,9 +105,9 @@ clauselist_selectivity(Query *root, List *clauses, int varRelid) { - Selectivity s1 = 1.0; - RangeQueryClause *rqlist = NULL; - List *clist; + Selectivity s1 = 1.0; + RangeQueryClause *rqlist = NULL; + List *clist; /* * Initial scan over clauses. Anything that doesn't look like a @@ -116,13 +117,13 @@ clauselist_selectivity(Query *root, foreach(clist, clauses) { Node *clause = (Node *) lfirst(clist); - Selectivity s2; + Selectivity s2; /* - * See if it looks like a restriction clause with a constant. - * (If it's not a constant we can't really trust the selectivity!) - * NB: for consistency of results, this fragment of code had - * better match what clause_selectivity() would do. + * See if it looks like a restriction clause with a constant. (If + * it's not a constant we can't really trust the selectivity!) NB: + * for consistency of results, this fragment of code had better + * match what clause_selectivity() would do. */ if (varRelid != 0 || NumRelids(clause) == 1) { @@ -147,11 +148,12 @@ clauselist_selectivity(Query *root, root->rtable), attno, constval, flag); + /* - * If we reach here, we have computed the same result - * that clause_selectivity would, so we can just use s2 - * if it's the wrong oprrest. But if it's the right - * oprrest, add the clause to rqlist for later processing. + * If we reach here, we have computed the same result that + * clause_selectivity would, so we can just use s2 if it's + * the wrong oprrest. But if it's the right oprrest, add + * the clause to rqlist for later processing. */ switch (oprrest) { @@ -166,7 +168,7 @@ clauselist_selectivity(Query *root, s1 = s1 * s2; break; } - continue; /* drop to loop bottom */ + continue; /* drop to loop bottom */ } } /* Not the right form, so treat it generically. */ @@ -179,12 +181,12 @@ clauselist_selectivity(Query *root, */ while (rqlist != NULL) { - RangeQueryClause *rqnext; + RangeQueryClause *rqnext; if (rqlist->have_lobound && rqlist->have_hibound) { /* Successfully matched a pair of range clauses */ - Selectivity s2 = rqlist->hibound + rqlist->lobound - 1.0; + Selectivity s2 = rqlist->hibound + rqlist->lobound - 1.0; /* * A zero or slightly negative s2 should be converted into a @@ -199,14 +201,20 @@ clauselist_selectivity(Query *root, { if (s2 < -0.01) { - /* No data available --- use a default estimate that + + /* + * No data available --- use a default estimate that * is small, but not real small. */ s2 = 0.01; } else { - /* It's just roundoff error; use a small positive value */ + + /* + * It's just roundoff error; use a small positive + * value + */ s2 = 1.0e-10; } } @@ -239,15 +247,15 @@ static void addRangeClause(RangeQueryClause **rqlist, Node *clause, int flag, bool isLTsel, Selectivity s2) { - RangeQueryClause *rqelem; - Node *var; - bool is_lobound; + RangeQueryClause *rqelem; + Node *var; + bool is_lobound; /* get_relattval sets flag&SEL_RIGHT if the var is on the LEFT. */ if (flag & SEL_RIGHT) { var = (Node *) get_leftop((Expr *) clause); - is_lobound = ! isLTsel; /* x < something is high bound */ + is_lobound = !isLTsel; /* x < something is high bound */ } else { @@ -257,23 +265,27 @@ addRangeClause(RangeQueryClause **rqlist, Node *clause, for (rqelem = *rqlist; rqelem; rqelem = rqelem->next) { - /* We use full equal() here because the "var" might be a function + + /* + * We use full equal() here because the "var" might be a function * of one or more attributes of the same relation... */ - if (! equal(var, rqelem->var)) + if (!equal(var, rqelem->var)) continue; /* Found the right group to put this clause in */ if (is_lobound) { - if (! rqelem->have_lobound) + if (!rqelem->have_lobound) { rqelem->have_lobound = true; rqelem->lobound = s2; } else { - /* We have found two similar clauses, such as - * x < y AND x < z. Keep only the more restrictive one. + + /* + * We have found two similar clauses, such as x < y AND x + * < z. Keep only the more restrictive one. */ if (rqelem->lobound > s2) rqelem->lobound = s2; @@ -281,15 +293,17 @@ addRangeClause(RangeQueryClause **rqlist, Node *clause, } else { - if (! rqelem->have_hibound) + if (!rqelem->have_hibound) { rqelem->have_hibound = true; rqelem->hibound = s2; } else { - /* We have found two similar clauses, such as - * x > y AND x > z. Keep only the more restrictive one. + + /* + * We have found two similar clauses, such as x > y AND x + * > z. Keep only the more restrictive one. */ if (rqelem->hibound > s2) rqelem->hibound = s2; @@ -331,7 +345,7 @@ addRangeClause(RangeQueryClause **rqlist, Node *clause, * nestloop join's inner relation --- varRelid should then be the ID of the * inner relation. * - * When varRelid is 0, all variables are treated as variables. This + * When varRelid is 0, all variables are treated as variables. This * is appropriate for ordinary join clauses and restriction clauses. */ Selectivity @@ -339,12 +353,13 @@ clause_selectivity(Query *root, Node *clause, int varRelid) { - Selectivity s1 = 1.0; /* default for any unhandled clause type */ + Selectivity s1 = 1.0; /* default for any unhandled clause type */ if (clause == NULL) return s1; if (IsA(clause, Var)) { + /* * we have a bool Var. This is exactly equivalent to the clause: * reln.attribute = 't' so we compute the selectivity as if that @@ -352,7 +367,7 @@ clause_selectivity(Query *root, * didn't want to have to do system cache look ups to find out all * of that info. */ - Index varno = ((Var *) clause)->varno; + Index varno = ((Var *) clause)->varno; if (varRelid == 0 || varRelid == (int) varno) s1 = restriction_selectivity(F_EQSEL, @@ -377,7 +392,7 @@ clause_selectivity(Query *root, { /* inverse of the selectivity of the underlying clause */ s1 = 1.0 - clause_selectivity(root, - (Node*) get_notclausearg((Expr*) clause), + (Node *) get_notclausearg((Expr *) clause), varRelid); } else if (and_clause(clause)) @@ -389,18 +404,21 @@ clause_selectivity(Query *root, } else if (or_clause(clause)) { + /* * Selectivities for an 'or' clause are computed as s1+s2 - s1*s2 - * to account for the probable overlap of selected tuple sets. - * XXX is this too conservative? + * to account for the probable overlap of selected tuple sets. XXX + * is this too conservative? */ - List *arg; + List *arg; + s1 = 0.0; foreach(arg, ((Expr *) clause)->args) { - Selectivity s2 = clause_selectivity(root, + Selectivity s2 = clause_selectivity(root, (Node *) lfirst(arg), varRelid); + s1 = s1 + s2 - s1 * s2; } } @@ -411,17 +429,20 @@ clause_selectivity(Query *root, if (varRelid != 0) { + /* - * If we are considering a nestloop join then all clauses - * are restriction clauses, since we are only interested in - * the one relation. + * If we are considering a nestloop join then all clauses are + * restriction clauses, since we are only interested in the + * one relation. */ is_join_clause = false; } else { + /* - * Otherwise, it's a join if there's more than one relation used. + * Otherwise, it's a join if there's more than one relation + * used. */ is_join_clause = (NumRelids(clause) > 1); } @@ -432,8 +453,8 @@ clause_selectivity(Query *root, RegProcedure oprjoin = get_oprjoin(opno); /* - * if the oprjoin procedure is missing for whatever reason, use a - * selectivity of 0.5 + * if the oprjoin procedure is missing for whatever reason, + * use a selectivity of 0.5 */ if (!oprjoin) s1 = (Selectivity) 0.5; @@ -460,8 +481,8 @@ clause_selectivity(Query *root, RegProcedure oprrest = get_oprrest(opno); /* - * if the oprrest procedure is missing for whatever reason, use a - * selectivity of 0.5 + * if the oprrest procedure is missing for whatever reason, + * use a selectivity of 0.5 */ if (!oprrest) s1 = (Selectivity) 0.5; @@ -484,6 +505,7 @@ clause_selectivity(Query *root, } else if (is_funcclause(clause)) { + /* * This is not an operator, so we guess at the selectivity. THIS * IS A HACK TO GET V4 OUT THE DOOR. FUNCS SHOULD BE ABLE TO HAVE @@ -493,6 +515,7 @@ clause_selectivity(Query *root, } else if (is_subplan(clause)) { + /* * Just for the moment! FIX ME! - vadim 02/04/98 */ diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c index f6bdcb828b9..6ecfb2a4713 100644 --- a/src/backend/optimizer/path/costsize.c +++ b/src/backend/optimizer/path/costsize.c @@ -19,7 +19,7 @@ * * Obviously, taking constants for these values is an oversimplification, * but it's tough enough to get any useful estimates even at this level of - * detail. Note that all of these parameters are user-settable, in case + * detail. Note that all of these parameters are user-settable, in case * the default values are drastically off for a particular platform. * * We compute two separate costs for each path: @@ -37,12 +37,12 @@ * will be no zero divide.) RelOptInfos, Paths, and Plans themselves never * account for LIMIT. * - * + * * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.56 2000/04/09 04:31:36 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.57 2000/04/12 17:15:19 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -118,6 +118,7 @@ cost_seqscan(Path *path, RelOptInfo *baserel) /* disk costs */ if (lfirsti(baserel->relids) < 0) { + /* * cost of sequentially scanning a materialized temporary relation */ @@ -125,15 +126,17 @@ cost_seqscan(Path *path, RelOptInfo *baserel) } else { + /* * The cost of reading a page sequentially is 1.0, by definition. * Note that the Unix kernel will typically do some amount of - * read-ahead optimization, so that this cost is less than the true - * cost of reading a page from disk. We ignore that issue here, - * but must take it into account when estimating the cost of + * read-ahead optimization, so that this cost is less than the + * true cost of reading a page from disk. We ignore that issue + * here, but must take it into account when estimating the cost of * non-sequential accesses! */ - run_cost += baserel->pages; /* sequential fetches with cost 1.0 */ + run_cost += baserel->pages; /* sequential fetches with cost + * 1.0 */ } /* CPU costs */ @@ -151,7 +154,7 @@ cost_seqscan(Path *path, RelOptInfo *baserel) * * The simplistic model that the cost is random_page_cost is what we want * to use for large relations; but for small ones that is a serious - * overestimate because of the effects of caching. This routine tries to + * overestimate because of the effects of caching. This routine tries to * account for that. * * Unfortunately we don't have any good way of estimating the effective cache @@ -221,12 +224,12 @@ cost_index(Path *path, Query *root, Cost cpu_per_tuple; Cost indexStartupCost; Cost indexTotalCost; - Selectivity indexSelectivity; + Selectivity indexSelectivity; double tuples_fetched; double pages_fetched; /* Should only be applied to base relations */ - Assert(IsA(baserel, RelOptInfo) && IsA(index, IndexOptInfo)); + Assert(IsA(baserel, RelOptInfo) &&IsA(index, IndexOptInfo)); Assert(length(baserel->relids) == 1); if (!enable_indexscan && !is_injoin) @@ -234,8 +237,9 @@ cost_index(Path *path, Query *root, /* * Call index-access-method-specific code to estimate the processing - * cost for scanning the index, as well as the selectivity of the index - * (ie, the fraction of main-table tuples we will have to retrieve). + * cost for scanning the index, as well as the selectivity of the + * index (ie, the fraction of main-table tuples we will have to + * retrieve). */ fmgr(index->amcostestimate, root, baserel, index, indexQuals, &indexStartupCost, &indexTotalCost, &indexSelectivity); @@ -249,17 +253,18 @@ cost_index(Path *path, Query *root, * * If the number of tuples is much smaller than the number of pages in * the relation, each tuple will cost a separate nonsequential fetch. - * If it is comparable or larger, then probably we will be able to avoid - * some fetches. We use a growth rate of log(#tuples/#pages + 1) --- - * probably totally bogus, but intuitively it gives the right shape of - * curve at least. + * If it is comparable or larger, then probably we will be able to + * avoid some fetches. We use a growth rate of log(#tuples/#pages + + * 1) --- probably totally bogus, but intuitively it gives the right + * shape of curve at least. * * XXX if the relation has recently been "clustered" using this index, - * then in fact the target tuples will be highly nonuniformly distributed, - * and we will be seriously overestimating the scan cost! Currently we - * have no way to know whether the relation has been clustered, nor how - * much it's been modified since the last clustering, so we ignore this - * effect. Would be nice to do better someday. + * then in fact the target tuples will be highly nonuniformly + * distributed, and we will be seriously overestimating the scan cost! + * Currently we have no way to know whether the relation has been + * clustered, nor how much it's been modified since the last + * clustering, so we ignore this effect. Would be nice to do better + * someday. */ tuples_fetched = indexSelectivity * baserel->tuples; @@ -274,8 +279,8 @@ cost_index(Path *path, Query *root, pages_fetched = tuples_fetched; /* - * Now estimate one nonsequential access per page fetched, - * plus appropriate CPU costs per tuple. + * Now estimate one nonsequential access per page fetched, plus + * appropriate CPU costs per tuple. */ /* disk costs for main table */ @@ -283,16 +288,18 @@ cost_index(Path *path, Query *root, /* CPU costs */ cpu_per_tuple = cpu_tuple_cost + baserel->baserestrictcost; + /* - * Normally the indexquals will be removed from the list of restriction - * clauses that we have to evaluate as qpquals, so we should subtract - * their costs from baserestrictcost. For a lossy index, however, we - * will have to recheck all the quals and so mustn't subtract anything. - * Also, if we are doing a join then some of the indexquals are join - * clauses and shouldn't be subtracted. Rather than work out exactly - * how much to subtract, we don't subtract anything in that case either. + * Normally the indexquals will be removed from the list of + * restriction clauses that we have to evaluate as qpquals, so we + * should subtract their costs from baserestrictcost. For a lossy + * index, however, we will have to recheck all the quals and so + * mustn't subtract anything. Also, if we are doing a join then some + * of the indexquals are join clauses and shouldn't be subtracted. + * Rather than work out exactly how much to subtract, we don't + * subtract anything in that case either. */ - if (! index->lossy && ! is_injoin) + if (!index->lossy && !is_injoin) cpu_per_tuple -= cost_qual_eval(indexQuals); run_cost += cpu_per_tuple * tuples_fetched; @@ -326,7 +333,7 @@ cost_tidscan(Path *path, RelOptInfo *baserel, List *tideval) path->startup_cost = startup_cost; path->total_cost = startup_cost + run_cost; } - + /* * cost_sort * Determines and returns the cost of sorting a relation. @@ -341,7 +348,7 @@ cost_tidscan(Path *path, RelOptInfo *baserel, List *tideval) * If the total volume exceeds SortMem, we switch to a tape-style merge * algorithm. There will still be about t*log2(t) tuple comparisons in * total, but we will also need to write and read each tuple once per - * merge pass. We expect about ceil(log6(r)) merge passes where r is the + * merge pass. We expect about ceil(log6(r)) merge passes where r is the * number of initial runs formed (log6 because tuplesort.c uses six-tape * merging). Since the average initial run should be about twice SortMem, * we have @@ -385,8 +392,8 @@ cost_sort(Path *path, List *pathkeys, double tuples, int width) /* * CPU costs * - * Assume about two operator evals per tuple comparison - * and N log2 N comparisons + * Assume about two operator evals per tuple comparison and N log2 N + * comparisons */ startup_cost += 2.0 * cpu_operator_cost * tuples * LOG2(tuples); @@ -408,7 +415,7 @@ cost_sort(Path *path, List *pathkeys, double tuples, int width) /* * Note: should we bother to assign a nonzero run_cost to reflect the - * overhead of extracting tuples from the sort result? Probably not + * overhead of extracting tuples from the sort result? Probably not * worth worrying about. */ path->startup_cost = startup_cost; @@ -440,19 +447,22 @@ cost_nestloop(Path *path, startup_cost += disable_cost; /* cost of source data */ + /* - * NOTE: we assume that the inner path's startup_cost is paid once, not - * over again on each restart. This is certainly correct if the inner - * path is materialized. Are there any cases where it is wrong? + * NOTE: we assume that the inner path's startup_cost is paid once, + * not over again on each restart. This is certainly correct if the + * inner path is materialized. Are there any cases where it is wrong? */ startup_cost += outer_path->startup_cost + inner_path->startup_cost; run_cost += outer_path->total_cost - outer_path->startup_cost; run_cost += outer_path->parent->rows * (inner_path->total_cost - inner_path->startup_cost); - /* Number of tuples processed (not number emitted!). If inner path is + /* + * Number of tuples processed (not number emitted!). If inner path is * an indexscan, be sure to use its estimated output row count, which - * may be lower than the restriction-clause-only row count of its parent. + * may be lower than the restriction-clause-only row count of its + * parent. */ if (IsA(inner_path, IndexPath)) ntuples = ((IndexPath *) inner_path)->rows; @@ -498,11 +508,12 @@ cost_mergejoin(Path *path, startup_cost += disable_cost; /* cost of source data */ + /* * Note we are assuming that each source tuple is fetched just once, - * which is not right in the presence of equal keys. If we had a way of - * estimating the proportion of equal keys, we could apply a correction - * factor... + * which is not right in the presence of equal keys. If we had a way + * of estimating the proportion of equal keys, we could apply a + * correction factor... */ if (outersortkeys) /* do we need to sort outer? */ { @@ -537,10 +548,10 @@ cost_mergejoin(Path *path, } /* - * Estimate the number of tuples to be processed in the mergejoin itself - * as one per tuple in the two source relations. This could be a drastic - * underestimate if there are many equal-keyed tuples in either relation, - * but we have no good way of estimating that... + * Estimate the number of tuples to be processed in the mergejoin + * itself as one per tuple in the two source relations. This could be + * a drastic underestimate if there are many equal-keyed tuples in + * either relation, but we have no good way of estimating that... */ ntuples = outer_path->parent->rows + inner_path->parent->rows; @@ -575,9 +586,9 @@ cost_hashjoin(Path *path, Cost cpu_per_tuple; double ntuples; double outerbytes = relation_byte_size(outer_path->parent->rows, - outer_path->parent->width); + outer_path->parent->width); double innerbytes = relation_byte_size(inner_path->parent->rows, - inner_path->parent->width); + inner_path->parent->width); long hashtablebytes = SortMem * 1024L; if (!enable_hashjoin) @@ -592,7 +603,8 @@ cost_hashjoin(Path *path, startup_cost += cpu_operator_cost * inner_path->parent->rows; run_cost += cpu_operator_cost * outer_path->parent->rows; - /* the number of tuple comparisons needed is the number of outer + /* + * the number of tuple comparisons needed is the number of outer * tuples times the typical hash bucket size, which we estimate * conservatively as the inner disbursion times the inner tuple count. */ @@ -601,9 +613,9 @@ cost_hashjoin(Path *path, /* * Estimate the number of tuples that get through the hashing filter - * as one per tuple in the two source relations. This could be a drastic - * underestimate if there are many equal-keyed tuples in either relation, - * but we have no good way of estimating that... + * as one per tuple in the two source relations. This could be a + * drastic underestimate if there are many equal-keyed tuples in + * either relation, but we have no good way of estimating that... */ ntuples = outer_path->parent->rows + inner_path->parent->rows; @@ -614,33 +626,31 @@ cost_hashjoin(Path *path, /* * if inner relation is too big then we will need to "batch" the join, * which implies writing and reading most of the tuples to disk an - * extra time. Charge one cost unit per page of I/O (correct since - * it should be nice and sequential...). Writing the inner rel counts - * as startup cost, all the rest as run cost. + * extra time. Charge one cost unit per page of I/O (correct since it + * should be nice and sequential...). Writing the inner rel counts as + * startup cost, all the rest as run cost. */ if (innerbytes > hashtablebytes) { - double outerpages = page_size(outer_path->parent->rows, - outer_path->parent->width); - double innerpages = page_size(inner_path->parent->rows, - inner_path->parent->width); + double outerpages = page_size(outer_path->parent->rows, + outer_path->parent->width); + double innerpages = page_size(inner_path->parent->rows, + inner_path->parent->width); startup_cost += innerpages; run_cost += innerpages + 2 * outerpages; } /* - * Bias against putting larger relation on inside. We don't want - * an absolute prohibition, though, since larger relation might have + * Bias against putting larger relation on inside. We don't want an + * absolute prohibition, though, since larger relation might have * better disbursion --- and we can't trust the size estimates - * unreservedly, anyway. Instead, inflate the startup cost by - * the square root of the size ratio. (Why square root? No real good + * unreservedly, anyway. Instead, inflate the startup cost by the + * square root of the size ratio. (Why square root? No real good * reason, but it seems reasonable...) */ if (innerbytes > outerbytes && outerbytes > 0) - { startup_cost *= sqrt(innerbytes / outerbytes); - } path->startup_cost = startup_cost; path->total_cost = startup_cost + run_cost; @@ -656,7 +666,7 @@ cost_hashjoin(Path *path, Cost cost_qual_eval(List *quals) { - Cost total = 0; + Cost total = 0; cost_qual_eval_walker((Node *) quals, &total); return total; @@ -667,10 +677,11 @@ cost_qual_eval_walker(Node *node, Cost *total) { if (node == NULL) return false; + /* * Our basic strategy is to charge one cpu_operator_cost for each - * operator or function node in the given tree. Vars and Consts - * are charged zero, and so are boolean operators (AND, OR, NOT). + * operator or function node in the given tree. Vars and Consts are + * charged zero, and so are boolean operators (AND, OR, NOT). * Simplistic, but a lot better than no model at all. * * Should we try to account for the possibility of short-circuit @@ -678,7 +689,7 @@ cost_qual_eval_walker(Node *node, Cost *total) */ if (IsA(node, Expr)) { - Expr *expr = (Expr *) node; + Expr *expr = (Expr *) node; switch (expr->opType) { @@ -691,17 +702,19 @@ cost_qual_eval_walker(Node *node, Cost *total) case NOT_EXPR: break; case SUBPLAN_EXPR: + /* - * A subplan node in an expression indicates that the subplan - * will be executed on each evaluation, so charge accordingly. - * (We assume that sub-selects that can be executed as - * InitPlans have already been removed from the expression.) + * A subplan node in an expression indicates that the + * subplan will be executed on each evaluation, so charge + * accordingly. (We assume that sub-selects that can be + * executed as InitPlans have already been removed from + * the expression.) * * NOTE: this logic should agree with the estimates used by - * make_subplan() in plan/subselect.c. + * make_subplan() in plan/subselect.c. */ { - SubPlan *subplan = (SubPlan *) expr->oper; + SubPlan *subplan = (SubPlan *) expr->oper; Plan *plan = subplan->plan; Cost subcost; @@ -730,13 +743,14 @@ cost_qual_eval_walker(Node *node, Cost *total) } /* fall through to examine args of Expr node */ } + /* - * expression_tree_walker doesn't know what to do with RestrictInfo nodes, - * but we just want to recurse through them. + * expression_tree_walker doesn't know what to do with RestrictInfo + * nodes, but we just want to recurse through them. */ if (IsA(node, RestrictInfo)) { - RestrictInfo *restrictinfo = (RestrictInfo *) node; + RestrictInfo *restrictinfo = (RestrictInfo *) node; return cost_qual_eval_walker((Node *) restrictinfo->clause, total); } @@ -755,7 +769,7 @@ cost_qual_eval_walker(Node *node, Cost *total) * * We set the following fields of the rel node: * rows: the estimated number of output tuples (after applying - * restriction clauses). + * restriction clauses). * width: the estimated average output tuple width in bytes. * baserestrictcost: estimated cost of evaluating baserestrictinfo clauses. */ @@ -769,9 +783,11 @@ set_baserel_size_estimates(Query *root, RelOptInfo *rel) restrictlist_selectivity(root, rel->baserestrictinfo, lfirsti(rel->relids)); + /* * Force estimate to be at least one row, to make explain output look - * better and to avoid possible divide-by-zero when interpolating cost. + * better and to avoid possible divide-by-zero when interpolating + * cost. */ if (rel->rows < 1.0) rel->rows = 1.0; @@ -812,10 +828,10 @@ set_joinrel_size_estimates(Query *root, RelOptInfo *rel, temp = outer_rel->rows * inner_rel->rows; /* - * Apply join restrictivity. Note that we are only considering clauses - * that become restriction clauses at this join level; we are not - * double-counting them because they were not considered in estimating - * the sizes of the component rels. + * Apply join restrictivity. Note that we are only considering + * clauses that become restriction clauses at this join level; we are + * not double-counting them because they were not considered in + * estimating the sizes of the component rels. */ temp *= restrictlist_selectivity(root, restrictlist, @@ -823,7 +839,8 @@ set_joinrel_size_estimates(Query *root, RelOptInfo *rel, /* * Force estimate to be at least one row, to make explain output look - * better and to avoid possible divide-by-zero when interpolating cost. + * better and to avoid possible divide-by-zero when interpolating + * cost. */ if (temp < 1.0) temp = 1.0; @@ -833,8 +850,8 @@ set_joinrel_size_estimates(Query *root, RelOptInfo *rel, * We could apply set_rel_width() to compute the output tuple width * from scratch, but at present it's always just the sum of the input * widths, so why work harder than necessary? If relnode.c is ever - * taught to remove unneeded columns from join targetlists, go back - * to using set_rel_width here. + * taught to remove unneeded columns from join targetlists, go back to + * using set_rel_width here. */ rel->width = outer_rel->width + inner_rel->width; } @@ -859,7 +876,7 @@ set_rel_width(Query *root, RelOptInfo *rel) * compute_attribute_width * Given a target list entry, find the size in bytes of the attribute. * - * If a field is variable-length, we make a default assumption. Would be + * If a field is variable-length, we make a default assumption. Would be * better if VACUUM recorded some stats about the average field width... * also, we have access to the atttypmod, but fail to use it... */ diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c index 8c63d9e1c38..98c5112f7c3 100644 --- a/src/backend/optimizer/path/indxpath.c +++ b/src/backend/optimizer/path/indxpath.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.81 2000/03/22 22:08:33 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.82 2000/04/12 17:15:19 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -46,62 +46,63 @@ #define is_indexable_operator(clause,opclass,relam,indexkey_on_left) \ (indexable_operator(clause,opclass,relam,indexkey_on_left) != InvalidOid) -typedef enum { +typedef enum +{ Prefix_None, Prefix_Partial, Prefix_Exact } Prefix_Status; static void match_index_orclauses(RelOptInfo *rel, IndexOptInfo *index, - List *restrictinfo_list); + List *restrictinfo_list); static List *match_index_orclause(RelOptInfo *rel, IndexOptInfo *index, - List *or_clauses, - List *other_matching_indices); + List *or_clauses, + List *other_matching_indices); static bool match_or_subclause_to_indexkey(RelOptInfo *rel, - IndexOptInfo *index, - Expr *clause); + IndexOptInfo *index, + Expr *clause); static List *group_clauses_by_indexkey(RelOptInfo *rel, IndexOptInfo *index, - int *indexkeys, Oid *classes, - List *restrictinfo_list); + int *indexkeys, Oid *classes, + List *restrictinfo_list); static List *group_clauses_by_ikey_for_joins(RelOptInfo *rel, - IndexOptInfo *index, - int *indexkeys, Oid *classes, - List *join_cinfo_list, - List *restr_cinfo_list); + IndexOptInfo *index, + int *indexkeys, Oid *classes, + List *join_cinfo_list, + List *restr_cinfo_list); static bool match_clause_to_indexkey(RelOptInfo *rel, IndexOptInfo *index, - int indexkey, Oid opclass, - Expr *clause, bool join); + int indexkey, Oid opclass, + Expr *clause, bool join); static bool pred_test(List *predicate_list, List *restrictinfo_list, - List *joininfo_list); + List *joininfo_list); static bool one_pred_test(Expr *predicate, List *restrictinfo_list); static bool one_pred_clause_expr_test(Expr *predicate, Node *clause); static bool one_pred_clause_test(Expr *predicate, Node *clause); static bool clause_pred_clause_test(Expr *predicate, Node *clause); static void indexable_joinclauses(RelOptInfo *rel, IndexOptInfo *index, - List *joininfo_list, List *restrictinfo_list, - List **clausegroups, List **outerrelids); + List *joininfo_list, List *restrictinfo_list, + List **clausegroups, List **outerrelids); static List *index_innerjoin(Query *root, RelOptInfo *rel, IndexOptInfo *index, - List *clausegroup_list, List *outerrelids_list); + List *clausegroup_list, List *outerrelids_list); static bool useful_for_mergejoin(RelOptInfo *rel, IndexOptInfo *index, - List *joininfo_list); + List *joininfo_list); static bool useful_for_ordering(Query *root, RelOptInfo *rel, - IndexOptInfo *index, - ScanDirection scandir); + IndexOptInfo *index, + ScanDirection scandir); static bool match_index_to_operand(int indexkey, Var *operand, - RelOptInfo *rel, IndexOptInfo *index); + RelOptInfo *rel, IndexOptInfo *index); static bool function_index_operand(Expr *funcOpnd, RelOptInfo *rel, - IndexOptInfo *index); + IndexOptInfo *index); static bool match_special_index_operator(Expr *clause, Oid opclass, Oid relam, - bool indexkey_on_left); + bool indexkey_on_left); static Prefix_Status like_fixed_prefix(char *patt, char **prefix); static Prefix_Status regex_fixed_prefix(char *patt, bool case_insensitive, - char **prefix); + char **prefix); static List *prefix_quals(Var *leftop, Oid expr_op, - char *prefix, Prefix_Status pstatus); -static char *make_greater_string(const char * str, Oid datatype); -static Oid find_operator(const char * opname, Oid datatype); -static Datum string_to_datum(const char * str, Oid datatype); -static Const *string_to_const(const char * str, Oid datatype); -static bool string_lessthan(const char * str1, const char * str2, - Oid datatype); + char *prefix, Prefix_Status pstatus); +static char *make_greater_string(const char *str, Oid datatype); +static Oid find_operator(const char *opname, Oid datatype); +static Datum string_to_datum(const char *str, Oid datatype); +static Const *string_to_const(const char *str, Oid datatype); +static bool string_lessthan(const char *str1, const char *str2, + Oid datatype); /* @@ -153,34 +154,34 @@ create_index_paths(Query *root, List *joinouterrelids; /* - * If this is a partial index, we can only use it if it passes - * the predicate test. + * If this is a partial index, we can only use it if it passes the + * predicate test. */ if (index->indpred != NIL) if (!pred_test(index->indpred, restrictinfo_list, joininfo_list)) continue; /* - * 1. Try matching the index against subclauses of restriction 'or' - * clauses (ie, 'or' clauses that reference only this relation). - * The restrictinfo nodes for the 'or' clauses are marked with lists - * of the matching indices. No paths are actually created now; - * that will be done in orindxpath.c after all indexes for the rel - * have been examined. (We need to do it that way because we can - * potentially use a different index for each subclause of an 'or', - * so we can't build a path for an 'or' clause until all indexes have - * been matched against it.) + * 1. Try matching the index against subclauses of restriction + * 'or' clauses (ie, 'or' clauses that reference only this + * relation). The restrictinfo nodes for the 'or' clauses are + * marked with lists of the matching indices. No paths are + * actually created now; that will be done in orindxpath.c after + * all indexes for the rel have been examined. (We need to do it + * that way because we can potentially use a different index for + * each subclause of an 'or', so we can't build a path for an 'or' + * clause until all indexes have been matched against it.) * * We don't even think about special handling of 'or' clauses that - * involve more than one relation (ie, are join clauses). - * Can we do anything useful with those? + * involve more than one relation (ie, are join clauses). Can we + * do anything useful with those? */ match_index_orclauses(rel, index, restrictinfo_list); /* - * 2. If the keys of this index match any of the available non-'or' - * restriction clauses, then create a path using those clauses - * as indexquals. + * 2. If the keys of this index match any of the available + * non-'or' restriction clauses, then create a path using those + * clauses as indexquals. */ restrictclauses = group_clauses_by_indexkey(rel, index, @@ -191,7 +192,7 @@ create_index_paths(Query *root, if (restrictclauses != NIL) add_path(rel, (Path *) create_index_path(root, rel, index, restrictclauses, - NoMovementScanDirection)); + NoMovementScanDirection)); /* * 3. If this index can be used for a mergejoin, then create an @@ -205,16 +206,17 @@ create_index_paths(Query *root, if (restrictclauses == NIL) { if (useful_for_mergejoin(rel, index, joininfo_list) || - useful_for_ordering(root, rel, index, ForwardScanDirection)) + useful_for_ordering(root, rel, index, ForwardScanDirection)) add_path(rel, (Path *) create_index_path(root, rel, index, NIL, ForwardScanDirection)); } + /* - * Currently, backwards scan is never considered except for the case - * of matching a query result ordering. Possibly should consider - * it in other places? + * Currently, backwards scan is never considered except for the + * case of matching a query result ordering. Possibly should + * consider it in other places? */ if (useful_for_ordering(root, rel, index, BackwardScanDirection)) add_path(rel, (Path *) @@ -223,11 +225,11 @@ create_index_paths(Query *root, BackwardScanDirection)); /* - * 4. Create an innerjoin index path for each combination of - * other rels used in available join clauses. These paths will - * be considered as the inner side of nestloop joins against - * those sets of other rels. indexable_joinclauses() finds sets - * of clauses that can be used with each combination of outer rels, + * 4. Create an innerjoin index path for each combination of other + * rels used in available join clauses. These paths will be + * considered as the inner side of nestloop joins against those + * sets of other rels. indexable_joinclauses() finds sets of + * clauses that can be used with each combination of outer rels, * and index_innerjoin builds the paths themselves. We add the * paths to the rel's innerjoin list, NOT to the result list. */ @@ -247,7 +249,7 @@ create_index_paths(Query *root, /**************************************************************************** - * ---- ROUTINES TO PROCESS 'OR' CLAUSES ---- + * ---- ROUTINES TO PROCESS 'OR' CLAUSES ---- ****************************************************************************/ @@ -280,6 +282,7 @@ match_index_orclauses(RelOptInfo *rel, if (restriction_is_or_clause(restrictinfo)) { + /* * Add this index to the subclause index list for each * subclause that it matches. @@ -309,7 +312,7 @@ match_index_orclauses(RelOptInfo *rel, * that have already been matched to subclauses within this * particular 'or' clause (i.e., a list previously generated by * this routine), or NIL if this routine has not previously been - * run for this 'or' clause. + * run for this 'or' clause. * * Returns a list of the form ((a b c) (d e f) nil (g h) ...) where * a,b,c are nodes of indices that match the first subclause in @@ -326,7 +329,8 @@ match_index_orclause(RelOptInfo *rel, List *index_list; List *clist; - /* first time through, we create list of same length as OR clause, + /* + * first time through, we create list of same length as OR clause, * containing an empty sublist for each subclause. */ if (!other_matching_indices) @@ -374,8 +378,8 @@ match_or_subclause_to_indexkey(RelOptInfo *rel, IndexOptInfo *index, Expr *clause) { - int indexkey = index->indexkeys[0]; - Oid opclass = index->classlist[0]; + int indexkey = index->indexkeys[0]; + Oid opclass = index->classlist[0]; if (and_clause((Node *) clause)) { @@ -400,10 +404,10 @@ match_or_subclause_to_indexkey(RelOptInfo *rel, * used as indexquals. * * In the simplest case this just means making a one-element list of the - * given opclause. However, if the OR subclause is an AND, we have to + * given opclause. However, if the OR subclause is an AND, we have to * scan it to find the opclause(s) that match the index. (There should * be at least one, if match_or_subclause_to_indexkey succeeded, but there - * could be more.) Also, we apply expand_indexqual_conditions() to convert + * could be more.) Also, we apply expand_indexqual_conditions() to convert * any special matching opclauses to indexable operators. * * The passed-in clause is not changed. @@ -413,9 +417,9 @@ extract_or_indexqual_conditions(RelOptInfo *rel, IndexOptInfo *index, Expr *orsubclause) { - List *quals = NIL; - int indexkey = index->indexkeys[0]; - Oid opclass = index->classlist[0]; + List *quals = NIL; + int indexkey = index->indexkeys[0]; + Oid opclass = index->classlist[0]; if (and_clause((Node *) orsubclause)) { @@ -514,8 +518,9 @@ group_clauses_by_indexkey(RelOptInfo *rel, clausegroup = lappend(clausegroup, rinfo); } - /* If no clauses match this key, we're done; we don't want to - * look at keys to its right. + /* + * If no clauses match this key, we're done; we don't want to look + * at keys to its right. */ if (clausegroup == NIL) break; @@ -533,7 +538,7 @@ group_clauses_by_indexkey(RelOptInfo *rel, /* * group_clauses_by_ikey_for_joins - * Generates a list of join clauses that can be used with an index + * Generates a list of join clauses that can be used with an index * to scan the inner side of a nestloop join. * * This is much like group_clauses_by_indexkey(), but we consider both @@ -593,8 +598,9 @@ group_clauses_by_ikey_for_joins(RelOptInfo *rel, clausegroup = lappend(clausegroup, rinfo); } - /* If no clauses match this key, we're done; we don't want to - * look at keys to its right. + /* + * If no clauses match this key, we're done; we don't want to look + * at keys to its right. */ if (clausegroup == NIL) break; @@ -607,8 +613,8 @@ group_clauses_by_ikey_for_joins(RelOptInfo *rel, } while (!DoneMatchingIndexKeys(indexkeys, index)); /* - * if no join clause was matched then there ain't clauses for - * joins at all. + * if no join clause was matched then there ain't clauses for joins at + * all. */ if (!jfound) { @@ -623,8 +629,8 @@ group_clauses_by_ikey_for_joins(RelOptInfo *rel, /* * match_clause_to_indexkey() - * Determines whether a restriction or join clause matches - * a key of an index. + * Determines whether a restriction or join clause matches + * a key of an index. * * To match, the clause: @@ -673,43 +679,46 @@ match_clause_to_indexkey(RelOptInfo *rel, *rightop; /* Clause must be a binary opclause. */ - if (! is_opclause((Node *) clause)) + if (!is_opclause((Node *) clause)) return false; leftop = get_leftop(clause); rightop = get_rightop(clause); - if (! leftop || ! rightop) + if (!leftop || !rightop) return false; if (!join) { + /* * Not considering joins, so check for clauses of the form: * (indexkey operator constant) or (constant operator indexkey). * We will accept a Param as being constant. */ - if ((IsA(rightop, Const) || IsA(rightop, Param)) && + if ((IsA(rightop, Const) ||IsA(rightop, Param)) && match_index_to_operand(indexkey, leftop, rel, index)) { if (is_indexable_operator(clause, opclass, index->relam, true)) return true; + /* - * If we didn't find a member of the index's opclass, - * see whether it is a "special" indexable operator. + * If we didn't find a member of the index's opclass, see + * whether it is a "special" indexable operator. */ if (match_special_index_operator(clause, opclass, index->relam, true)) return true; return false; } - if ((IsA(leftop, Const) || IsA(leftop, Param)) && + if ((IsA(leftop, Const) ||IsA(leftop, Param)) && match_index_to_operand(indexkey, rightop, rel, index)) { if (is_indexable_operator(clause, opclass, index->relam, false)) return true; + /* - * If we didn't find a member of the index's opclass, - * see whether it is a "special" indexable operator. + * If we didn't find a member of the index's opclass, see + * whether it is a "special" indexable operator. */ if (match_special_index_operator(clause, opclass, index->relam, false)) @@ -719,20 +728,21 @@ match_clause_to_indexkey(RelOptInfo *rel, } else { + /* - * Check for an indexqual that could be handled by a nestloop join. - * We need the index key to be compared against an expression - * that uses none of the indexed relation's vars. + * Check for an indexqual that could be handled by a nestloop + * join. We need the index key to be compared against an + * expression that uses none of the indexed relation's vars. */ if (match_index_to_operand(indexkey, leftop, rel, index)) { List *othervarnos = pull_varnos((Node *) rightop); bool isIndexable; - isIndexable = ! intMember(lfirsti(rel->relids), othervarnos); + isIndexable = !intMember(lfirsti(rel->relids), othervarnos); freeList(othervarnos); if (isIndexable && - is_indexable_operator(clause, opclass, index->relam, true)) + is_indexable_operator(clause, opclass, index->relam, true)) return true; } else if (match_index_to_operand(indexkey, rightop, rel, index)) @@ -740,10 +750,10 @@ match_clause_to_indexkey(RelOptInfo *rel, List *othervarnos = pull_varnos((Node *) leftop); bool isIndexable; - isIndexable = ! intMember(lfirsti(rel->relids), othervarnos); + isIndexable = !intMember(lfirsti(rel->relids), othervarnos); freeList(othervarnos); if (isIndexable && - is_indexable_operator(clause, opclass, index->relam, false)) + is_indexable_operator(clause, opclass, index->relam, false)) return true; } } @@ -768,7 +778,7 @@ match_clause_to_indexkey(RelOptInfo *rel, * * Returns the OID of the matching operator, or InvalidOid if no match. * Note that the returned OID will be different from the one in the given - * expression if we used a binary-compatible substitution. Also note that + * expression if we used a binary-compatible substitution. Also note that * if indexkey_on_left is FALSE (meaning we need to commute), the returned * OID is *not* commuted; it can be plugged directly into the given clause. */ @@ -818,13 +828,14 @@ indexable_operator(Expr *clause, Oid opclass, Oid relam, if (HeapTupleIsValid(newop)) { - Oid new_expr_op = oprid(newop); + Oid new_expr_op = oprid(newop); if (new_expr_op != expr_op) { + /* - * OK, we found a binary-compatible operator of the same name; - * now does it match the index? + * OK, we found a binary-compatible operator of the same + * name; now does it match the index? */ if (indexkey_on_left) commuted_op = new_expr_op; @@ -883,12 +894,12 @@ useful_for_mergejoin(RelOptInfo *rel, { if (restrictinfo->left_sortop == ordering[0] && match_index_to_operand(indexkeys[0], - get_leftop(restrictinfo->clause), + get_leftop(restrictinfo->clause), rel, index)) return true; if (restrictinfo->right_sortop == ordering[0] && match_index_to_operand(indexkeys[0], - get_rightop(restrictinfo->clause), + get_rightop(restrictinfo->clause), rel, index)) return true; } @@ -1127,7 +1138,7 @@ one_pred_clause_test(Expr *predicate, Node *clause) */ static StrategyNumber -BT_implic_table[BTMaxStrategyNumber][BTMaxStrategyNumber] = { + BT_implic_table[BTMaxStrategyNumber][BTMaxStrategyNumber] = { {2, 2, 0, 0, 0}, {1, 2, 0, 0, 0}, {1, 2, 3, 4, 5}, @@ -1346,13 +1357,13 @@ clause_pred_clause_test(Expr *predicate, Node *clause) * rel's restrictinfo list. Therefore, every clause in the group references * the current rel plus the same set of other rels (except for the restrict * clauses, which only reference the current rel). Therefore, this set - * of clauses could be used as an indexqual if the relation is scanned + * of clauses could be used as an indexqual if the relation is scanned * as the inner side of a nestloop join when the outer side contains * (at least) all those "other rels". * * XXX Actually, given that we are considering a join that requires an * outer rel set (A,B,C), we should use all qual clauses that reference - * any subset of these rels, not just the full set or none. This is + * any subset of these rels, not just the full set or none. This is * doable with a doubly nested loop over joininfo_list; is it worth it? * * Returns two parallel lists of the same length: the clause groups, @@ -1430,10 +1441,11 @@ index_innerjoin(Query *root, RelOptInfo *rel, IndexOptInfo *index, pathnode->path.pathtype = T_IndexScan; pathnode->path.parent = rel; + /* * There's no point in marking the path with any pathkeys, since - * it will only ever be used as the inner path of a nestloop, - * and so its ordering does not matter. + * it will only ever be used as the inner path of a nestloop, and + * so its ordering does not matter. */ pathnode->path.pathkeys = NIL; @@ -1441,7 +1453,8 @@ index_innerjoin(Query *root, RelOptInfo *rel, IndexOptInfo *index, /* expand special operators to indexquals the executor can handle */ indexquals = expand_indexqual_conditions(indexquals); - /* Note that we are making a pathnode for a single-scan indexscan; + /* + * Note that we are making a pathnode for a single-scan indexscan; * therefore, both indexid and indexqual should be single-element * lists. */ @@ -1456,14 +1469,15 @@ index_innerjoin(Query *root, RelOptInfo *rel, IndexOptInfo *index, /* * We must compute the estimated number of output rows for the - * indexscan. This is less than rel->rows because of the additional - * selectivity of the join clauses. Since clausegroup may contain - * both restriction and join clauses, we have to do a set union to - * get the full set of clauses that must be considered to compute - * the correct selectivity. (We can't just nconc the two lists; - * then we might have some restriction clauses appearing twice, - * which'd mislead restrictlist_selectivity into double-counting - * their selectivity.) + * indexscan. This is less than rel->rows because of the + * additional selectivity of the join clauses. Since clausegroup + * may contain both restriction and join clauses, we have to do a + * set union to get the full set of clauses that must be + * considered to compute the correct selectivity. (We can't just + * nconc the two lists; then we might have some restriction + * clauses appearing twice, which'd mislead + * restrictlist_selectivity into double-counting their + * selectivity.) */ pathnode->rows = rel->tuples * restrictlist_selectivity(root, @@ -1490,7 +1504,7 @@ index_innerjoin(Query *root, RelOptInfo *rel, IndexOptInfo *index, * match_index_to_operand() * Generalized test for a match between an index's key * and the operand on one side of a restriction or join clause. - * Now check for functional indices as well. + * Now check for functional indices as well. */ static bool match_index_to_operand(int indexkey, @@ -1500,6 +1514,7 @@ match_index_to_operand(int indexkey, { if (index->indproc == InvalidOid) { + /* * Normal index. */ @@ -1530,7 +1545,7 @@ function_index_operand(Expr *funcOpnd, RelOptInfo *rel, IndexOptInfo *index) /* * sanity check, make sure we know what we're dealing with here. */ - if (funcOpnd == NULL || ! IsA(funcOpnd, Expr) || + if (funcOpnd == NULL || !IsA(funcOpnd, Expr) || funcOpnd->opType != FUNC_EXPR || funcOpnd->oper == NULL || indexKeys == NULL) return false; @@ -1550,9 +1565,9 @@ function_index_operand(Expr *funcOpnd, RelOptInfo *rel, IndexOptInfo *index) i = 0; foreach(arg, funcargs) { - Var *var = (Var *) lfirst(arg); + Var *var = (Var *) lfirst(arg); - if (! IsA(var, Var)) + if (!IsA(var, Var)) return false; if (indexKeys[i] == 0) return false; @@ -1578,10 +1593,10 @@ function_index_operand(Expr *funcOpnd, RelOptInfo *rel, IndexOptInfo *index) * indexscan machinery. The key idea is that these operators allow us * to derive approximate indexscan qual clauses, such that any tuples * that pass the operator clause itself must also satisfy the simpler - * indexscan condition(s). Then we can use the indexscan machinery + * indexscan condition(s). Then we can use the indexscan machinery * to avoid scanning as much of the table as we'd otherwise have to, * while applying the original operator as a qpqual condition to ensure - * we deliver only the tuples we want. (In essence, we're using a regular + * we deliver only the tuples we want. (In essence, we're using a regular * index as if it were a lossy index.) * * An example of what we're doing is @@ -1630,11 +1645,12 @@ match_special_index_operator(Expr *clause, Oid opclass, Oid relam, char *patt; char *prefix; - /* Currently, all known special operators require the indexkey - * on the left, but this test could be pushed into the switch statement - * if some are added that do not... + /* + * Currently, all known special operators require the indexkey on the + * left, but this test could be pushed into the switch statement if + * some are added that do not... */ - if (! indexkey_on_left) + if (!indexkey_on_left) return false; /* we know these will succeed */ @@ -1643,7 +1659,7 @@ match_special_index_operator(Expr *clause, Oid opclass, Oid relam, expr_op = ((Oper *) clause->oper)->opno; /* again, required for all current special ops: */ - if (! IsA(rightop, Const) || + if (!IsA(rightop, Const) || ((Const *) rightop)->constisnull) return false; constvalue = ((Const *) rightop)->constvalue; @@ -1657,7 +1673,8 @@ match_special_index_operator(Expr *clause, Oid opclass, Oid relam, /* the right-hand const is type text for all of these */ patt = textout((text *) DatumGetPointer(constvalue)); isIndexable = like_fixed_prefix(patt, &prefix) != Prefix_None; - if (prefix) pfree(prefix); + if (prefix) + pfree(prefix); pfree(patt); break; @@ -1668,7 +1685,8 @@ match_special_index_operator(Expr *clause, Oid opclass, Oid relam, /* the right-hand const is type text for all of these */ patt = textout((text *) DatumGetPointer(constvalue)); isIndexable = regex_fixed_prefix(patt, false, &prefix) != Prefix_None; - if (prefix) pfree(prefix); + if (prefix) + pfree(prefix); pfree(patt); break; @@ -1679,13 +1697,14 @@ match_special_index_operator(Expr *clause, Oid opclass, Oid relam, /* the right-hand const is type text for all of these */ patt = textout((text *) DatumGetPointer(constvalue)); isIndexable = regex_fixed_prefix(patt, true, &prefix) != Prefix_None; - if (prefix) pfree(prefix); + if (prefix) + pfree(prefix); pfree(patt); break; } /* done if the expression doesn't look indexable */ - if (! isIndexable) + if (!isIndexable) return false; /* @@ -1699,32 +1718,32 @@ match_special_index_operator(Expr *clause, Oid opclass, Oid relam, case OID_TEXT_LIKE_OP: case OID_TEXT_REGEXEQ_OP: case OID_TEXT_ICREGEXEQ_OP: - if (! op_class(find_operator(">=", TEXTOID), opclass, relam) || - ! op_class(find_operator("<", TEXTOID), opclass, relam)) + if (!op_class(find_operator(">=", TEXTOID), opclass, relam) || + !op_class(find_operator("<", TEXTOID), opclass, relam)) isIndexable = false; break; case OID_BPCHAR_LIKE_OP: case OID_BPCHAR_REGEXEQ_OP: case OID_BPCHAR_ICREGEXEQ_OP: - if (! op_class(find_operator(">=", BPCHAROID), opclass, relam) || - ! op_class(find_operator("<", BPCHAROID), opclass, relam)) + if (!op_class(find_operator(">=", BPCHAROID), opclass, relam) || + !op_class(find_operator("<", BPCHAROID), opclass, relam)) isIndexable = false; break; case OID_VARCHAR_LIKE_OP: case OID_VARCHAR_REGEXEQ_OP: case OID_VARCHAR_ICREGEXEQ_OP: - if (! op_class(find_operator(">=", VARCHAROID), opclass, relam) || - ! op_class(find_operator("<", VARCHAROID), opclass, relam)) + if (!op_class(find_operator(">=", VARCHAROID), opclass, relam) || + !op_class(find_operator("<", VARCHAROID), opclass, relam)) isIndexable = false; break; case OID_NAME_LIKE_OP: case OID_NAME_REGEXEQ_OP: case OID_NAME_ICREGEXEQ_OP: - if (! op_class(find_operator(">=", NAMEOID), opclass, relam) || - ! op_class(find_operator("<", NAMEOID), opclass, relam)) + if (!op_class(find_operator(">=", NAMEOID), opclass, relam) || + !op_class(find_operator("<", NAMEOID), opclass, relam)) isIndexable = false; break; } @@ -1736,7 +1755,7 @@ match_special_index_operator(Expr *clause, Oid opclass, Oid relam, * expand_indexqual_conditions * Given a list of (implicitly ANDed) indexqual clauses, * expand any "special" index operators into clauses that the indexscan - * machinery will know what to do with. Clauses that were not + * machinery will know what to do with. Clauses that were not * recognized by match_special_index_operator() must be passed through * unchanged. */ @@ -1749,6 +1768,7 @@ expand_indexqual_conditions(List *indexquals) foreach(q, indexquals) { Expr *clause = (Expr *) lfirst(q); + /* we know these will succeed */ Var *leftop = get_leftop(clause); Var *rightop = get_rightop(clause); @@ -1760,11 +1780,13 @@ expand_indexqual_conditions(List *indexquals) switch (expr_op) { - /* - * LIKE and regex operators are not members of any index opclass, - * so if we find one in an indexqual list we can assume that - * it was accepted by match_special_index_operator(). - */ + + /* + * LIKE and regex operators are not members of any index + * opclass, so if we find one in an indexqual list we can + * assume that it was accepted by + * match_special_index_operator(). + */ case OID_TEXT_LIKE_OP: case OID_BPCHAR_LIKE_OP: case OID_VARCHAR_LIKE_OP: @@ -1776,7 +1798,8 @@ expand_indexqual_conditions(List *indexquals) resultquals = nconc(resultquals, prefix_quals(leftop, expr_op, prefix, pstatus)); - if (prefix) pfree(prefix); + if (prefix) + pfree(prefix); pfree(patt); break; @@ -1791,7 +1814,8 @@ expand_indexqual_conditions(List *indexquals) resultquals = nconc(resultquals, prefix_quals(leftop, expr_op, prefix, pstatus)); - if (prefix) pfree(prefix); + if (prefix) + pfree(prefix); pfree(patt); break; @@ -1806,7 +1830,8 @@ expand_indexqual_conditions(List *indexquals) resultquals = nconc(resultquals, prefix_quals(leftop, expr_op, prefix, pstatus)); - if (prefix) pfree(prefix); + if (prefix) + pfree(prefix); pfree(patt); break; @@ -1833,7 +1858,7 @@ like_fixed_prefix(char *patt, char **prefix) int pos, match_pos; - *prefix = match = palloc(strlen(patt)+1); + *prefix = match = palloc(strlen(patt) + 1); match_pos = 0; for (pos = 0; patt[pos]; pos++) @@ -1849,14 +1874,15 @@ like_fixed_prefix(char *patt, char **prefix) if (patt[pos] == '\0') break; } + /* - * NOTE: this code used to think that %% meant a literal %, - * but textlike() itself does not think that, and the SQL92 - * spec doesn't say any such thing either. + * NOTE: this code used to think that %% meant a literal %, but + * textlike() itself does not think that, and the SQL92 spec + * doesn't say any such thing either. */ match[match_pos++] = patt[pos]; } - + match[match_pos] = '\0'; /* in LIKE, an empty pattern is an exact match! */ @@ -1905,7 +1931,7 @@ regex_fixed_prefix(char *patt, bool case_insensitive, } /* OK, allocate space for pattern */ - *prefix = match = palloc(strlen(patt)+1); + *prefix = match = palloc(strlen(patt) + 1); match_pos = 0; /* note start at pos 1 to skip leading ^ */ @@ -1916,9 +1942,11 @@ regex_fixed_prefix(char *patt, bool case_insensitive, patt[pos] == '*' || patt[pos] == '[' || patt[pos] == '$' || - /* XXX I suspect isalpha() is not an adequately locale-sensitive - * test for characters that can vary under case folding? - */ + + /* + * XXX I suspect isalpha() is not an adequately locale-sensitive + * test for characters that can vary under case folding? + */ (case_insensitive && isalpha(patt[pos]))) break; if (patt[pos] == '\\') @@ -1932,9 +1960,9 @@ regex_fixed_prefix(char *patt, bool case_insensitive, match[match_pos] = '\0'; - if (patt[pos] == '$' && patt[pos+1] == '\0') + if (patt[pos] == '$' && patt[pos + 1] == '\0') return Prefix_Exact; /* pattern specifies exact match */ - + if (match_pos > 0) return Prefix_Partial; return Prefix_None; @@ -2020,7 +2048,8 @@ prefix_quals(Var *leftop, Oid expr_op, result = lcons(expr, NIL); /* - * If we can create a string larger than the prefix, say "x < greaterstr". + * If we can create a string larger than the prefix, say "x < + * greaterstr". */ greaterstr = make_greater_string(prefix, datatype); if (greaterstr) @@ -2058,17 +2087,20 @@ prefix_quals(Var *leftop, Oid expr_op, * given "foos" and return "foot", will this actually be greater than "fooss"? */ static char * -make_greater_string(const char * str, Oid datatype) +make_greater_string(const char *str, Oid datatype) { char *workstr; int len; - /* Make a modifiable copy, which will be our return value if successful */ + /* + * Make a modifiable copy, which will be our return value if + * successful + */ workstr = pstrdup((char *) str); while ((len = strlen(workstr)) > 0) { - unsigned char *lastchar = (unsigned char *) (workstr + len - 1); + unsigned char *lastchar = (unsigned char *) (workstr + len - 1); /* * Try to generate a larger string by incrementing the last byte. @@ -2077,14 +2109,15 @@ make_greater_string(const char * str, Oid datatype) { (*lastchar)++; if (string_lessthan(str, workstr, datatype)) - return workstr; /* Success! */ + return workstr; /* Success! */ } + /* - * Truncate off the last character, which might be more than 1 byte - * in MULTIBYTE case. + * Truncate off the last character, which might be more than 1 + * byte in MULTIBYTE case. */ #ifdef MULTIBYTE - len = pg_mbcliplen((const unsigned char *) workstr, len, len-1); + len = pg_mbcliplen((const unsigned char *) workstr, len, len - 1); workstr[len] = '\0'; #else *lastchar = '\0'; @@ -2102,7 +2135,7 @@ make_greater_string(const char * str, Oid datatype) /* See if there is a binary op of the given name for the given datatype */ static Oid -find_operator(const char * opname, Oid datatype) +find_operator(const char *opname, Oid datatype) { HeapTuple optup; @@ -2122,10 +2155,12 @@ find_operator(const char * opname, Oid datatype) * returned value should be pfree'd if no longer needed. */ static Datum -string_to_datum(const char * str, Oid datatype) +string_to_datum(const char *str, Oid datatype) { - /* We cheat a little by assuming that textin() will do for - * bpchar and varchar constants too... + + /* + * We cheat a little by assuming that textin() will do for bpchar and + * varchar constants too... */ if (datatype == NAMEOID) return PointerGetDatum(namein((char *) str)); @@ -2137,7 +2172,7 @@ string_to_datum(const char * str, Oid datatype) * Generate a Const node of the appropriate type from a C string. */ static Const * -string_to_const(const char * str, Oid datatype) +string_to_const(const char *str, Oid datatype) { Datum conval = string_to_datum(str, datatype); @@ -2151,7 +2186,7 @@ string_to_const(const char * str, Oid datatype) * "<" operator function, to ensure we get the right result... */ static bool -string_lessthan(const char * str1, const char * str2, Oid datatype) +string_lessthan(const char *str1, const char *str2, Oid datatype) { Datum datum1 = string_to_datum(str1, datatype); Datum datum2 = string_to_datum(str2, datatype); diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c index 92614374968..64e9443ab18 100644 --- a/src/backend/optimizer/path/joinpath.c +++ b/src/backend/optimizer/path/joinpath.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinpath.c,v 1.53 2000/02/18 23:47:19 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinpath.c,v 1.54 2000/04/12 17:15:19 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -28,25 +28,27 @@ #include "utils/lsyscache.h" static void sort_inner_and_outer(Query *root, RelOptInfo *joinrel, - RelOptInfo *outerrel, RelOptInfo *innerrel, - List *restrictlist, List *mergeclause_list); + RelOptInfo *outerrel, RelOptInfo *innerrel, + List *restrictlist, List *mergeclause_list); static void match_unsorted_outer(Query *root, RelOptInfo *joinrel, - RelOptInfo *outerrel, RelOptInfo *innerrel, - List *restrictlist, List *mergeclause_list); + RelOptInfo *outerrel, RelOptInfo *innerrel, + List *restrictlist, List *mergeclause_list); + #ifdef NOT_USED static void match_unsorted_inner(Query *root, RelOptInfo *joinrel, - RelOptInfo *outerrel, RelOptInfo *innerrel, - List *restrictlist, List *mergeclause_list); + RelOptInfo *outerrel, RelOptInfo *innerrel, + List *restrictlist, List *mergeclause_list); + #endif static void hash_inner_and_outer(Query *root, RelOptInfo *joinrel, - RelOptInfo *outerrel, RelOptInfo *innerrel, - List *restrictlist); + RelOptInfo *outerrel, RelOptInfo *innerrel, + List *restrictlist); static Path *best_innerjoin(List *join_paths, List *outer_relid); static Selectivity estimate_disbursion(Query *root, Var *var); static List *select_mergejoin_clauses(RelOptInfo *joinrel, - RelOptInfo *outerrel, - RelOptInfo *innerrel, - List *restrictlist); + RelOptInfo *outerrel, + RelOptInfo *innerrel, + List *restrictlist); /* @@ -79,32 +81,33 @@ add_paths_to_joinrel(Query *root, restrictlist); /* - * 1. Consider mergejoin paths where both relations must be - * explicitly sorted. + * 1. Consider mergejoin paths where both relations must be explicitly + * sorted. */ sort_inner_and_outer(root, joinrel, outerrel, innerrel, restrictlist, mergeclause_list); /* - * 2. Consider paths where the outer relation need not be - * explicitly sorted. This includes both nestloops and - * mergejoins where the outer path is already ordered. + * 2. Consider paths where the outer relation need not be explicitly + * sorted. This includes both nestloops and mergejoins where the outer + * path is already ordered. */ match_unsorted_outer(root, joinrel, outerrel, innerrel, restrictlist, mergeclause_list); #ifdef NOT_USED + /* - * 3. Consider paths where the inner relation need not be - * explicitly sorted. This includes mergejoins only - * (nestloops were already built in match_unsorted_outer). + * 3. Consider paths where the inner relation need not be explicitly + * sorted. This includes mergejoins only (nestloops were already + * built in match_unsorted_outer). * - * Diked out as redundant 2/13/2000 -- tgl. There isn't any - * really significant difference between the inner and outer - * side of a mergejoin, so match_unsorted_inner creates no paths - * that aren't equivalent to those made by match_unsorted_outer - * when add_paths_to_joinrel() is invoked with the two rels given - * in the other order. + * Diked out as redundant 2/13/2000 -- tgl. There isn't any really + * significant difference between the inner and outer side of a + * mergejoin, so match_unsorted_inner creates no paths that aren't + * equivalent to those made by match_unsorted_outer when + * add_paths_to_joinrel() is invoked with the two rels given in the + * other order. */ match_unsorted_inner(root, joinrel, outerrel, innerrel, restrictlist, mergeclause_list); @@ -144,31 +147,31 @@ sort_inner_and_outer(Query *root, /* * Each possible ordering of the available mergejoin clauses will - * generate a differently-sorted result path at essentially the - * same cost. We have no basis for choosing one over another at - * this level of joining, but some sort orders may be more useful - * than others for higher-level mergejoins. Generating a path here - * for *every* permutation of mergejoin clauses doesn't seem like - * a winning strategy, however; the cost in planning time is too high. + * generate a differently-sorted result path at essentially the same + * cost. We have no basis for choosing one over another at this level + * of joining, but some sort orders may be more useful than others for + * higher-level mergejoins. Generating a path here for *every* + * permutation of mergejoin clauses doesn't seem like a winning + * strategy, however; the cost in planning time is too high. * * For now, we generate one path for each mergejoin clause, listing that - * clause first and the rest in random order. This should allow at least - * a one-clause mergejoin without re-sorting against any other possible - * mergejoin partner path. But if we've not guessed the right ordering - * of secondary clauses, we may end up evaluating clauses as qpquals when - * they could have been done as mergeclauses. We need to figure out a - * better way. (Two possible approaches: look at all the relevant index - * relations to suggest plausible sort orders, or make just one output - * path and somehow mark it as having a sort-order that can be rearranged - * freely.) + * clause first and the rest in random order. This should allow at + * least a one-clause mergejoin without re-sorting against any other + * possible mergejoin partner path. But if we've not guessed the + * right ordering of secondary clauses, we may end up evaluating + * clauses as qpquals when they could have been done as mergeclauses. + * We need to figure out a better way. (Two possible approaches: look + * at all the relevant index relations to suggest plausible sort + * orders, or make just one output path and somehow mark it as having + * a sort-order that can be rearranged freely.) */ foreach(i, mergeclause_list) { - RestrictInfo *restrictinfo = lfirst(i); - List *curclause_list; - List *outerkeys; - List *innerkeys; - List *merge_pathkeys; + RestrictInfo *restrictinfo = lfirst(i); + List *curclause_list; + List *outerkeys; + List *innerkeys; + List *merge_pathkeys; /* Make a mergeclause list with this guy first. */ if (i != mergeclause_list) @@ -176,13 +179,14 @@ sort_inner_and_outer(Query *root, lremove(restrictinfo, listCopy(mergeclause_list))); else - curclause_list = mergeclause_list; /* no work at first one... */ + curclause_list = mergeclause_list; /* no work at first one... */ - /* Build sort pathkeys for both sides. + /* + * Build sort pathkeys for both sides. * - * Note: it's possible that the cheapest paths will already be - * sorted properly. create_mergejoin_path will detect that case - * and suppress an explicit sort step, so we needn't do so here. + * Note: it's possible that the cheapest paths will already be sorted + * properly. create_mergejoin_path will detect that case and + * suppress an explicit sort step, so we needn't do so here. */ outerkeys = make_pathkeys_for_mergeclauses(root, curclause_list, @@ -198,8 +202,8 @@ sort_inner_and_outer(Query *root, /* * And now we can make the path. We only consider the cheapest- * total-cost input paths, since we are assuming here that a sort - * is required. We will consider cheapest-startup-cost input paths - * later, and only if they don't need a sort. + * is required. We will consider cheapest-startup-cost input + * paths later, and only if they don't need a sort. */ add_path(joinrel, (Path *) create_mergejoin_path(joinrel, @@ -225,7 +229,7 @@ sort_inner_and_outer(Query *root, * inner path, one on the cheapest-startup-cost inner path (if different), * and one on the best inner-indexscan path (if any). * - * We also consider mergejoins if mergejoin clauses are available. We have + * We also consider mergejoins if mergejoin clauses are available. We have * two ways to generate the inner path for a mergejoin: sort the cheapest * inner path, or use an inner path that is already suitably ordered for the * merge. If we have several mergeclauses, it could be that there is no inner @@ -255,8 +259,8 @@ match_unsorted_outer(Query *root, List *i; /* - * Get the best innerjoin indexpath (if any) for this outer rel. - * It's the same for all outer paths. + * Get the best innerjoin indexpath (if any) for this outer rel. It's + * the same for all outer paths. */ bestinnerjoin = best_innerjoin(innerrel->innerjoin, outerrel->relids); @@ -274,8 +278,8 @@ match_unsorted_outer(Query *root, /* * The result will have this sort order (even if it is implemented - * as a nestloop, and even if some of the mergeclauses are implemented - * by qpquals rather than as true mergeclauses): + * as a nestloop, and even if some of the mergeclauses are + * implemented by qpquals rather than as true mergeclauses): */ merge_pathkeys = build_join_pathkeys(outerpath->pathkeys, joinrel->targetlist, @@ -318,11 +322,12 @@ match_unsorted_outer(Query *root, /* Compute the required ordering of the inner path */ innersortkeys = make_pathkeys_for_mergeclauses(root, mergeclauses, - innerrel->targetlist); + innerrel->targetlist); /* - * Generate a mergejoin on the basis of sorting the cheapest inner. - * Since a sort will be needed, only cheapest total cost matters. + * Generate a mergejoin on the basis of sorting the cheapest + * inner. Since a sort will be needed, only cheapest total cost + * matters. */ add_path(joinrel, (Path *) create_mergejoin_path(joinrel, @@ -335,11 +340,11 @@ match_unsorted_outer(Query *root, innersortkeys)); /* - * Look for presorted inner paths that satisfy the mergeclause list - * or any truncation thereof. Here, we consider both cheap startup - * cost and cheap total cost. + * Look for presorted inner paths that satisfy the mergeclause + * list or any truncation thereof. Here, we consider both cheap + * startup cost and cheap total cost. */ - trialsortkeys = listCopy(innersortkeys); /* modifiable copy */ + trialsortkeys = listCopy(innersortkeys); /* modifiable copy */ cheapest_startup_inner = NULL; cheapest_total_inner = NULL; num_mergeclauses = length(mergeclauses); @@ -349,8 +354,9 @@ match_unsorted_outer(Query *root, Path *innerpath; List *newclauses = NIL; - /* Look for an inner path ordered well enough to merge with - * the first 'clausecnt' mergeclauses. NB: trialsortkeys list + /* + * Look for an inner path ordered well enough to merge with + * the first 'clausecnt' mergeclauses. NB: trialsortkeys list * is modified destructively, which is why we made a copy... */ trialsortkeys = ltruncate(clausecnt, trialsortkeys); @@ -391,14 +397,16 @@ match_unsorted_outer(Query *root, /* Found a cheap (or even-cheaper) sorted path */ if (innerpath != cheapest_total_inner) { - /* Avoid rebuilding clause list if we already made one; - * saves memory in big join trees... + + /* + * Avoid rebuilding clause list if we already made + * one; saves memory in big join trees... */ if (newclauses == NIL) { if (clausecnt < num_mergeclauses) newclauses = ltruncate(clausecnt, - listCopy(mergeclauses)); + listCopy(mergeclauses)); else newclauses = mergeclauses; } @@ -461,11 +469,12 @@ match_unsorted_inner(Query *root, /* Compute the required ordering of the outer path */ outersortkeys = make_pathkeys_for_mergeclauses(root, mergeclauses, - outerrel->targetlist); + outerrel->targetlist); /* - * Generate a mergejoin on the basis of sorting the cheapest outer. - * Since a sort will be needed, only cheapest total cost matters. + * Generate a mergejoin on the basis of sorting the cheapest + * outer. Since a sort will be needed, only cheapest total cost + * matters. */ merge_pathkeys = build_join_pathkeys(outersortkeys, joinrel->targetlist, @@ -479,10 +488,11 @@ match_unsorted_inner(Query *root, mergeclauses, outersortkeys, NIL)); + /* * Now generate mergejoins based on already-sufficiently-ordered - * outer paths. There's likely to be some redundancy here with paths - * already generated by merge_unsorted_outer ... but since + * outer paths. There's likely to be some redundancy here with + * paths already generated by merge_unsorted_outer ... but since * merge_unsorted_outer doesn't consider all permutations of the * mergeclause list, it may fail to notice that this particular * innerpath could have been used with this outerpath. @@ -491,7 +501,8 @@ match_unsorted_inner(Query *root, outersortkeys, TOTAL_COST); if (totalouterpath == NULL) - continue; /* there won't be a startup-cost path either */ + continue; /* there won't be a startup-cost path + * either */ merge_pathkeys = build_join_pathkeys(totalouterpath->pathkeys, joinrel->targetlist, @@ -552,8 +563,8 @@ hash_inner_and_outer(Query *root, List *i; /* - * Scan the join's restrictinfo list to find hashjoinable clauses - * that are usable with this pair of sub-relations. Since we currently + * Scan the join's restrictinfo list to find hashjoinable clauses that + * are usable with this pair of sub-relations. Since we currently * accept only var-op-var clauses as hashjoinable, we need only check * the membership of the vars to determine whether a particular clause * can be used with this pair of sub-relations. This code would need @@ -568,7 +579,7 @@ hash_inner_and_outer(Query *root, *right, *inner; List *hashclauses; - Selectivity innerdisbursion; + Selectivity innerdisbursion; if (restrictinfo->hashjoinoperator == InvalidOid) continue; /* not hashjoinable */ @@ -595,9 +606,9 @@ hash_inner_and_outer(Query *root, innerdisbursion = estimate_disbursion(root, inner); /* - * We consider both the cheapest-total-cost and cheapest-startup-cost - * outer paths. There's no need to consider any but the cheapest- - * total-cost inner path, however. + * We consider both the cheapest-total-cost and + * cheapest-startup-cost outer paths. There's no need to consider + * any but the cheapest- total-cost inner path, however. */ add_path(joinrel, (Path *) create_hashjoin_path(joinrel, @@ -644,7 +655,8 @@ best_innerjoin(List *join_paths, Relids outer_relids) Assert(IsA(path, IndexPath)); - /* path->joinrelids is the set of base rels that must be part of + /* + * path->joinrelids is the set of base rels that must be part of * outer_relids in order to use this inner path, because those * rels are used in the index join quals of this inner path. */ @@ -661,7 +673,7 @@ best_innerjoin(List *join_paths, Relids outer_relids) * * We use a default of 0.1 if we can't figure out anything better. * This will typically discourage use of a hash rather strongly, - * if the inner relation is large. We do not want to hash unless + * if the inner relation is large. We do not want to hash unless * we know that the inner rel is well-dispersed (or the alternatives * seem much worse). */ @@ -670,7 +682,7 @@ estimate_disbursion(Query *root, Var *var) { Oid relid; - if (! IsA(var, Var)) + if (!IsA(var, Var)) return 0.1; relid = getrelid(var->varno, root->rtable); @@ -690,7 +702,7 @@ estimate_disbursion(Query *root, Var *var) * Since we currently allow only plain Vars as the left and right sides * of mergejoin clauses, this test is relatively simple. This routine * would need to be upgraded to support more-complex expressions - * as sides of mergejoins. In theory, we could allow arbitrarily complex + * as sides of mergejoins. In theory, we could allow arbitrarily complex * expressions in mergejoins, so long as one side uses only vars from one * sub-relation and the other side uses only vars from the other. */ diff --git a/src/backend/optimizer/path/joinrels.c b/src/backend/optimizer/path/joinrels.c index e872b67623a..09003eb9fa8 100644 --- a/src/backend/optimizer/path/joinrels.c +++ b/src/backend/optimizer/path/joinrels.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinrels.c,v 1.43 2000/02/07 04:40:59 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinrels.c,v 1.44 2000/04/12 17:15:20 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -22,7 +22,7 @@ static RelOptInfo *make_join_rel(Query *root, RelOptInfo *rel1, - RelOptInfo *rel2); + RelOptInfo *rel2); /* @@ -44,22 +44,23 @@ make_rels_by_joins(Query *root, int level) /* * First, consider left-sided and right-sided plans, in which rels of * exactly level-1 member relations are joined against base relations. - * We prefer to join using join clauses, but if we find a rel of level-1 - * members that has no join clauses, we will generate Cartesian-product - * joins against all base rels not already contained in it. + * We prefer to join using join clauses, but if we find a rel of + * level-1 members that has no join clauses, we will generate + * Cartesian-product joins against all base rels not already contained + * in it. * * In the first pass (level == 2), we try to join each base rel to each * base rel that appears later in base_rel_list. (The mirror-image - * joins are handled automatically by make_join_rel.) In later passes, - * we try to join rels of size level-1 from join_rel_list to each - * base rel in base_rel_list. + * joins are handled automatically by make_join_rel.) In later + * passes, we try to join rels of size level-1 from join_rel_list to + * each base rel in base_rel_list. * * We assume that the rels already present in join_rel_list appear in * decreasing order of level (number of members). This should be true * since we always add new higher-level rels to the front of the list. */ if (level == 2) - r = root->base_rel_list; /* level-1 is base rels */ + r = root->base_rel_list;/* level-1 is base rels */ else r = root->join_rel_list; for (; r != NIL; r = lnext(r)) @@ -68,21 +69,23 @@ make_rels_by_joins(Query *root, int level) int old_level = length(old_rel->relids); List *other_rels; - if (old_level != level-1) + if (old_level != level - 1) break; if (level == 2) - other_rels = lnext(r); /* only consider remaining base rels */ + other_rels = lnext(r); /* only consider remaining base + * rels */ else - other_rels = root->base_rel_list; /* consider all base rels */ + other_rels = root->base_rel_list; /* consider all base rels */ if (old_rel->joininfo != NIL) { + /* - * Note that if all available join clauses for this rel require - * more than one other rel, we will fail to make any joins against - * it here. That's OK; it'll be considered by "bushy plan" join - * code in a higher-level pass. + * Note that if all available join clauses for this rel + * require more than one other rel, we will fail to make any + * joins against it here. That's OK; it'll be considered by + * "bushy plan" join code in a higher-level pass. */ make_rels_by_clause_joins(root, old_rel, @@ -90,6 +93,7 @@ make_rels_by_joins(Query *root, int level) } else { + /* * Oops, we have a relation that is not joined to any other * relation. Cartesian product time. @@ -103,10 +107,11 @@ make_rels_by_joins(Query *root, int level) /* * Now, consider "bushy plans" in which relations of k base rels are * joined to relations of level-k base rels, for 2 <= k <= level-2. - * The previous loop left r pointing to the first rel of level level-2. + * The previous loop left r pointing to the first rel of level + * level-2. * - * We only consider bushy-plan joins for pairs of rels where there is - * a suitable join clause, in order to avoid unreasonable growth of + * We only consider bushy-plan joins for pairs of rels where there is a + * suitable join clause, in order to avoid unreasonable growth of * planning time. */ for (; r != NIL; r = lnext(r)) @@ -115,8 +120,9 @@ make_rels_by_joins(Query *root, int level) int old_level = length(old_rel->relids); List *r2; - /* We can quit once past the halfway point (make_join_rel took care - * of making the opposite-direction joins) + /* + * We can quit once past the halfway point (make_join_rel took + * care of making the opposite-direction joins) */ if (old_level * 2 < level) break; @@ -137,8 +143,10 @@ make_rels_by_joins(Query *root, int level) { List *i; - /* OK, we can build a rel of the right level from this pair of - * rels. Do so if there is at least one usable join clause. + /* + * OK, we can build a rel of the right level from this + * pair of rels. Do so if there is at least one usable + * join clause. */ foreach(i, old_rel->joininfo) { @@ -192,7 +200,7 @@ make_rels_by_clause_joins(Query *root, foreach(j, other_rels) { - RelOptInfo *other_rel = (RelOptInfo *) lfirst(j); + RelOptInfo *other_rel = (RelOptInfo *) lfirst(j); if (is_subseti(unjoined_relids, other_rel->relids)) result = make_join_rel(root, old_rel, other_rel); @@ -251,8 +259,8 @@ make_rels_by_clauseless_joins(Query *root, static RelOptInfo * make_join_rel(Query *root, RelOptInfo *rel1, RelOptInfo *rel2) { - RelOptInfo *joinrel; - List *restrictlist; + RelOptInfo *joinrel; + List *restrictlist; /* * Find or build the join RelOptInfo, and compute the restrictlist diff --git a/src/backend/optimizer/path/orindxpath.c b/src/backend/optimizer/path/orindxpath.c index e2ae3f0577a..85e96d6b86c 100644 --- a/src/backend/optimizer/path/orindxpath.c +++ b/src/backend/optimizer/path/orindxpath.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/path/orindxpath.c,v 1.38 2000/03/22 22:08:33 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/path/orindxpath.c,v 1.39 2000/04/12 17:15:20 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -27,14 +27,14 @@ static void best_or_subclause_indices(Query *root, RelOptInfo *rel, - List *subclauses, List *indices, - IndexPath *pathnode); + List *subclauses, List *indices, + IndexPath *pathnode); static void best_or_subclause_index(Query *root, RelOptInfo *rel, - Expr *subclause, List *indices, - List **retIndexQual, - Oid *retIndexid, - Cost *retStartupCost, - Cost *retTotalCost); + Expr *subclause, List *indices, + List **retIndexQual, + Oid *retIndexid, + Cost *retStartupCost, + Cost *retTotalCost); /* @@ -61,8 +61,8 @@ create_or_index_paths(Query *root, /* * Check to see if this clause is an 'or' clause, and, if so, * whether or not each of the subclauses within the 'or' clause - * has been matched by an index. The information used was - * saved by create_index_paths(). + * has been matched by an index. The information used was saved + * by create_index_paths(). */ if (restriction_is_or_clause(clausenode) && clausenode->subclauseindices) @@ -80,6 +80,7 @@ create_or_index_paths(Query *root, } if (all_indexable) { + /* * OK, build an IndexPath for this OR clause, using the * best available index for each subclause. @@ -88,19 +89,23 @@ create_or_index_paths(Query *root, pathnode->path.pathtype = T_IndexScan; pathnode->path.parent = rel; + /* - * This is an IndexScan, but the overall result will consist - * of tuples extracted in multiple passes (one for each - * subclause of the OR), so the result cannot be claimed - * to have any particular ordering. + * This is an IndexScan, but the overall result will + * consist of tuples extracted in multiple passes (one for + * each subclause of the OR), so the result cannot be + * claimed to have any particular ordering. */ pathnode->path.pathkeys = NIL; - /* We don't actually care what order the index scans in ... */ + /* + * We don't actually care what order the index scans in + * ... + */ pathnode->indexscandir = NoMovementScanDirection; /* This isn't a nestloop innerjoin, so: */ - pathnode->joinrelids = NIL; /* no join clauses here */ + pathnode->joinrelids = NIL; /* no join clauses here */ pathnode->rows = rel->rows; best_or_subclause_indices(root, @@ -125,7 +130,7 @@ create_or_index_paths(Query *root, * This routine also creates the indexqual and indexid lists that will * be needed by the executor. The indexqual list has one entry for each * scan of the base rel, which is a sublist of indexqual conditions to - * apply in that scan. The implicit semantics are AND across each sublist + * apply in that scan. The implicit semantics are AND across each sublist * of quals, and OR across the toplevel list (note that the executor * takes care not to return any single tuple more than once). The indexid * list gives the OID of the index to be used in each scan. @@ -181,7 +186,7 @@ best_or_subclause_indices(Query *root, pathnode->indexqual = lappend(pathnode->indexqual, best_indexqual); pathnode->indexid = lappendi(pathnode->indexid, best_indexid); - if (slist == subclauses) /* first scan? */ + if (slist == subclauses)/* first scan? */ pathnode->path.startup_cost = best_startup_cost; pathnode->path.total_cost += best_total_cost; diff --git a/src/backend/optimizer/path/pathkeys.c b/src/backend/optimizer/path/pathkeys.c index d5fbf82eb50..580675a85b7 100644 --- a/src/backend/optimizer/path/pathkeys.c +++ b/src/backend/optimizer/path/pathkeys.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/path/pathkeys.c,v 1.20 2000/02/18 23:47:19 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/path/pathkeys.c,v 1.21 2000/04/12 17:15:20 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -28,7 +28,7 @@ static PathKeyItem *makePathKeyItem(Node *key, Oid sortop); static List *make_canonical_pathkey(Query *root, PathKeyItem *item); static Var *find_indexkey_var(Query *root, RelOptInfo *rel, - AttrNumber varattno); + AttrNumber varattno); /*-------------------- @@ -42,8 +42,8 @@ static Var *find_indexkey_var(Query *root, RelOptInfo *rel, * of scanning the relation and the resulting ordering of the tuples. * Sequential scan Paths have NIL pathkeys, indicating no known ordering. * Index scans have Path.pathkeys that represent the chosen index's ordering, - * if any. A single-key index would create a pathkey with a single sublist, - * e.g. ( (tab1.indexkey1/sortop1) ). A multi-key index generates a sublist + * if any. A single-key index would create a pathkey with a single sublist, + * e.g. ( (tab1.indexkey1/sortop1) ). A multi-key index generates a sublist * per key, e.g. ( (tab1.indexkey1/sortop1) (tab1.indexkey2/sortop2) ) which * shows major sort by indexkey1 (ordering by sortop1) and minor sort by * indexkey2 with sortop2. @@ -56,10 +56,10 @@ static Var *find_indexkey_var(Query *root, RelOptInfo *rel, * ordering operators used. * * Things get more interesting when we consider joins. Suppose we do a - * mergejoin between A and B using the mergeclause A.X = B.Y. The output + * mergejoin between A and B using the mergeclause A.X = B.Y. The output * of the mergejoin is sorted by X --- but it is also sorted by Y. We * represent this fact by listing both keys in a single pathkey sublist: - * ( (A.X/xsortop B.Y/ysortop) ). This pathkey asserts that the major + * ( (A.X/xsortop B.Y/ysortop) ). This pathkey asserts that the major * sort order of the Path can be taken to be *either* A.X or B.Y. * They are equal, so they are both primary sort keys. By doing this, * we allow future joins to use either var as a pre-sorted key, so upper @@ -120,12 +120,12 @@ static Var *find_indexkey_var(Query *root, RelOptInfo *rel, * We did implement pathkeys just as described above, and found that the * planner spent a huge amount of time comparing pathkeys, because the * representation of pathkeys as unordered lists made it expensive to decide - * whether two were equal or not. So, we've modified the representation + * whether two were equal or not. So, we've modified the representation * as described next. * * If we scan the WHERE clause for equijoin clauses (mergejoinable clauses) * during planner startup, we can construct lists of equivalent pathkey items - * for the query. There could be more than two items per equivalence set; + * for the query. There could be more than two items per equivalence set; * for example, WHERE A.X = B.Y AND B.Y = C.Z AND D.R = E.S creates the * equivalence sets { A.X B.Y C.Z } and { D.R E.S } (plus associated sortops). * Any pathkey item that belongs to an equivalence set implies that all the @@ -147,20 +147,20 @@ static Var *find_indexkey_var(Query *root, RelOptInfo *rel, * equivalence set, we instantly add all the other vars equivalenced to it, * whether they appear yet in the pathkey's relation or not. And we also * mandate that the pathkey sublist appear in the same order as the - * equivalence set it comes from. (In practice, we simply return a pointer + * equivalence set it comes from. (In practice, we simply return a pointer * to the relevant equivalence set without building any new sublist at all.) * This makes comparing pathkeys very simple and fast, and saves a lot of * work and memory space for pathkey construction as well. * * Note that pathkey sublists having just one item still exist, and are - * not expected to be equal() to any equivalence set. This occurs when + * not expected to be equal() to any equivalence set. This occurs when * we describe a sort order that involves a var that's not mentioned in * any equijoin clause of the WHERE. We could add singleton sets containing * such vars to the query's list of equivalence sets, but there's little * point in doing so. * * By the way, it's OK and even useful for us to build equivalence sets - * that mention multiple vars from the same relation. For example, if + * that mention multiple vars from the same relation. For example, if * we have WHERE A.X = A.Y and we are scanning A using an index on X, * we can legitimately conclude that the path is sorted by Y as well; * and this could be handy if Y is the variable used in other join clauses @@ -179,7 +179,7 @@ static Var *find_indexkey_var(Query *root, RelOptInfo *rel, static PathKeyItem * makePathKeyItem(Node *key, Oid sortop) { - PathKeyItem *item = makeNode(PathKeyItem); + PathKeyItem *item = makeNode(PathKeyItem); item->key = key; item->sortop = sortop; @@ -219,11 +219,13 @@ add_equijoined_keys(Query *root, RestrictInfo *restrictinfo) /* We might see a clause X=X; don't make a single-element list from it */ if (equal(item1, item2)) return; + /* - * Our plan is to make a two-element set, then sweep through the existing - * equijoin sets looking for matches to item1 or item2. When we find one, - * we remove that set from equi_key_list and union it into our new set. - * When done, we add the new set to the front of equi_key_list. + * Our plan is to make a two-element set, then sweep through the + * existing equijoin sets looking for matches to item1 or item2. When + * we find one, we remove that set from equi_key_list and union it + * into our new set. When done, we add the new set to the front of + * equi_key_list. * * This is a standard UNION-FIND problem, for which there exist better * data structures than simple lists. If this code ever proves to be @@ -240,8 +242,11 @@ add_equijoined_keys(Query *root, RestrictInfo *restrictinfo) { /* Found a set to merge into our new set */ newset = LispUnion(newset, curset); - /* Remove old set from equi_key_list. NOTE this does not change - * lnext(cursetlink), so the outer foreach doesn't break. + + /* + * Remove old set from equi_key_list. NOTE this does not + * change lnext(cursetlink), so the outer foreach doesn't + * break. */ root->equi_key_list = lremove(curset, root->equi_key_list); freeList(curset); /* might as well recycle old cons cells */ @@ -256,7 +261,7 @@ add_equijoined_keys(Query *root, RestrictInfo *restrictinfo) * Given a PathKeyItem, find the equi_key_list subset it is a member of, * if any. If so, return a pointer to that sublist, which is the * canonical representation (for this query) of that PathKeyItem's - * equivalence set. If it is not found, return a single-element list + * equivalence set. If it is not found, return a single-element list * containing the PathKeyItem (when the item has no equivalence peers, * we just allow it to be a standalone list). * @@ -293,13 +298,13 @@ canonicalize_pathkeys(Query *root, List *pathkeys) foreach(i, pathkeys) { - List *pathkey = (List *) lfirst(i); - PathKeyItem *item; + List *pathkey = (List *) lfirst(i); + PathKeyItem *item; /* - * It's sufficient to look at the first entry in the sublist; - * if there are more entries, they're already part of an - * equivalence set by definition. + * It's sufficient to look at the first entry in the sublist; if + * there are more entries, they're already part of an equivalence + * set by definition. */ Assert(pathkey != NIL); item = (PathKeyItem *) lfirst(pathkey); @@ -319,12 +324,12 @@ canonicalize_pathkeys(Query *root, List *pathkeys) * one is "better" than the other. * * A pathkey can be considered better than another if it is a superset: - * it contains all the keys of the other plus more. For example, either + * it contains all the keys of the other plus more. For example, either * ((A) (B)) or ((A B)) is better than ((A)). * * Because we actually only expect to see canonicalized pathkey sublists, * we don't have to do the full two-way-subset-inclusion test on each - * pair of sublists that is implied by the above statement. Instead we + * pair of sublists that is implied by the above statement. Instead we * just do an equal(). In the normal case where multi-element sublists * are pointers into the root's equi_key_list, equal() will be very fast: * it will recognize pointer equality when the sublists are the same, @@ -345,23 +350,25 @@ compare_pathkeys(List *keys1, List *keys2) List *subkey1 = lfirst(key1); List *subkey2 = lfirst(key2); - /* We will never have two subkeys where one is a subset of the other, - * because of the canonicalization explained above. Either they are - * equal or they ain't. + /* + * We will never have two subkeys where one is a subset of the + * other, because of the canonicalization explained above. Either + * they are equal or they ain't. */ - if (! equal(subkey1, subkey2)) - return PATHKEYS_DIFFERENT; /* no need to keep looking */ + if (!equal(subkey1, subkey2)) + return PATHKEYS_DIFFERENT; /* no need to keep looking */ } - /* If we reached the end of only one list, the other is longer and - * therefore not a subset. (We assume the additional sublist(s) - * of the other list are not NIL --- no pathkey list should ever have - * a NIL sublist.) + /* + * If we reached the end of only one list, the other is longer and + * therefore not a subset. (We assume the additional sublist(s) of + * the other list are not NIL --- no pathkey list should ever have a + * NIL sublist.) */ if (key1 == NIL && key2 == NIL) return PATHKEYS_EQUAL; if (key1 != NIL) - return PATHKEYS_BETTER1; /* key1 is longer */ + return PATHKEYS_BETTER1;/* key1 is longer */ return PATHKEYS_BETTER2; /* key2 is longer */ } @@ -375,8 +382,8 @@ pathkeys_contained_in(List *keys1, List *keys2) { switch (compare_pathkeys(keys1, keys2)) { - case PATHKEYS_EQUAL: - case PATHKEYS_BETTER2: + case PATHKEYS_EQUAL: + case PATHKEYS_BETTER2: return true; default: break; @@ -448,7 +455,7 @@ get_cheapest_fractional_path_for_pathkeys(List *paths, * do that first. */ if (matched_path != NULL && - compare_fractional_path_costs(matched_path, path, fraction) <= 0) + compare_fractional_path_costs(matched_path, path, fraction) <= 0) continue; if (pathkeys_contained_in(pathkeys, path->pathkeys)) @@ -469,7 +476,7 @@ get_cheapest_fractional_path_for_pathkeys(List *paths, * its "ordering" field, and we will return NIL.) * * If 'scandir' is BackwardScanDirection, attempt to build pathkeys - * representing a backwards scan of the index. Return NIL if can't do it. + * representing a backwards scan of the index. Return NIL if can't do it. */ List * build_index_pathkeys(Query *root, @@ -527,7 +534,7 @@ build_index_pathkeys(Query *root, /* Normal non-functional index */ while (*indexkeys != 0 && *ordering != InvalidOid) { - Var *relvar = find_indexkey_var(root, rel, *indexkeys); + Var *relvar = find_indexkey_var(root, rel, *indexkeys); sortop = *ordering; if (ScanDirectionIsBackward(scandir)) @@ -569,9 +576,9 @@ find_indexkey_var(Query *root, RelOptInfo *rel, AttrNumber varattno) foreach(temp, rel->targetlist) { - Var *tle_var = get_expr(lfirst(temp)); + Var *tle_var = get_expr(lfirst(temp)); - if (IsA(tle_var, Var) && tle_var->varattno == varattno) + if (IsA(tle_var, Var) &&tle_var->varattno == varattno) return tle_var; } @@ -606,11 +613,12 @@ build_join_pathkeys(List *outer_pathkeys, List *join_rel_tlist, List *equi_key_list) { + /* * This used to be quite a complex bit of code, but now that all - * pathkey sublists start out life canonicalized, we don't have to - * do a darn thing here! The inner-rel vars we used to need to add - * are *already* part of the outer pathkey! + * pathkey sublists start out life canonicalized, we don't have to do + * a darn thing here! The inner-rel vars we used to need to add are + * *already* part of the outer pathkey! * * I'd remove the routine entirely, but maybe someday we'll need it... */ @@ -644,16 +652,17 @@ make_pathkeys_for_sortclauses(List *sortclauses, foreach(i, sortclauses) { - SortClause *sortcl = (SortClause *) lfirst(i); - Node *sortkey; - PathKeyItem *pathkey; + SortClause *sortcl = (SortClause *) lfirst(i); + Node *sortkey; + PathKeyItem *pathkey; sortkey = get_sortgroupclause_expr(sortcl, tlist); pathkey = makePathKeyItem(sortkey, sortcl->sortop); + /* * The pathkey becomes a one-element sublist, for now; - * canonicalize_pathkeys() might replace it with a longer - * sublist later. + * canonicalize_pathkeys() might replace it with a longer sublist + * later. */ pathkeys = lappend(pathkeys, lcons(pathkey, NIL)); } @@ -691,28 +700,28 @@ find_mergeclauses_for_pathkeys(List *pathkeys, List *restrictinfos) foreach(i, pathkeys) { - List *pathkey = lfirst(i); - RestrictInfo *matched_restrictinfo = NULL; - List *j; + List *pathkey = lfirst(i); + RestrictInfo *matched_restrictinfo = NULL; + List *j; /* - * We can match any of the keys in this pathkey sublist, - * since they're all equivalent. And we can match against - * either left or right side of any mergejoin clause we haven't - * used yet. For the moment we use a dumb "greedy" algorithm - * with no backtracking. Is it worth being any smarter to - * make a longer list of usable mergeclauses? Probably not. + * We can match any of the keys in this pathkey sublist, since + * they're all equivalent. And we can match against either left + * or right side of any mergejoin clause we haven't used yet. For + * the moment we use a dumb "greedy" algorithm with no + * backtracking. Is it worth being any smarter to make a longer + * list of usable mergeclauses? Probably not. */ foreach(j, pathkey) { - PathKeyItem *keyitem = lfirst(j); - Node *key = keyitem->key; - Oid keyop = keyitem->sortop; - List *k; + PathKeyItem *keyitem = lfirst(j); + Node *key = keyitem->key; + Oid keyop = keyitem->sortop; + List *k; foreach(k, restrictinfos) { - RestrictInfo *restrictinfo = lfirst(k); + RestrictInfo *restrictinfo = lfirst(k); Assert(restrictinfo->mergejoinoperator != InvalidOid); @@ -720,7 +729,7 @@ find_mergeclauses_for_pathkeys(List *pathkeys, List *restrictinfos) equal(key, get_leftop(restrictinfo->clause))) || (keyop == restrictinfo->right_sortop && equal(key, get_rightop(restrictinfo->clause)))) && - ! member(restrictinfo, mergeclauses)) + !member(restrictinfo, mergeclauses)) { matched_restrictinfo = restrictinfo; break; @@ -732,11 +741,12 @@ find_mergeclauses_for_pathkeys(List *pathkeys, List *restrictinfos) /* * If we didn't find a mergeclause, we're done --- any additional - * sort-key positions in the pathkeys are useless. (But we can + * sort-key positions in the pathkeys are useless. (But we can * still mergejoin if we found at least one mergeclause.) */ - if (! matched_restrictinfo) + if (!matched_restrictinfo) break; + /* * If we did find a usable mergeclause for this sort-key position, * add it to result list. @@ -756,7 +766,7 @@ find_mergeclauses_for_pathkeys(List *pathkeys, List *restrictinfos) * 'mergeclauses' is a list of RestrictInfos for mergejoin clauses * that will be used in a merge join. * 'tlist' is a relation target list for either the inner or outer - * side of the proposed join rel. (Not actually needed anymore) + * side of the proposed join rel. (Not actually needed anymore) * * Returns a pathkeys list that can be applied to the indicated relation. * @@ -785,24 +795,26 @@ make_pathkeys_for_mergeclauses(Query *root, /* * Find the key and sortop needed for this mergeclause. * - * Both sides of the mergeclause should appear in one of the - * query's pathkey equivalence classes, so it doesn't matter - * which one we use here. + * Both sides of the mergeclause should appear in one of the query's + * pathkey equivalence classes, so it doesn't matter which one we + * use here. */ key = (Node *) get_leftop(restrictinfo->clause); sortop = restrictinfo->left_sortop; + /* - * Find pathkey sublist for this sort item. We expect to find - * the canonical set including the mergeclause's left and right - * sides; if we get back just the one item, something is rotten. + * Find pathkey sublist for this sort item. We expect to find the + * canonical set including the mergeclause's left and right sides; + * if we get back just the one item, something is rotten. */ item = makePathKeyItem(key, sortop); pathkey = make_canonical_pathkey(root, item); Assert(length(pathkey) > 1); + /* - * Since the item we just made is not in the returned canonical set, - * we can free it --- this saves a useful amount of storage in a - * big join tree. + * Since the item we just made is not in the returned canonical + * set, we can free it --- this saves a useful amount of storage + * in a big join tree. */ pfree(item); diff --git a/src/backend/optimizer/path/tidpath.c b/src/backend/optimizer/path/tidpath.c index 1e7dc43473b..7824e0e3d2f 100644 --- a/src/backend/optimizer/path/tidpath.c +++ b/src/backend/optimizer/path/tidpath.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/path/tidpath.c,v 1.5 2000/02/15 20:49:17 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/path/tidpath.c,v 1.6 2000/04/12 17:15:20 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -37,30 +37,34 @@ #include "utils/lsyscache.h" static void create_tidscan_joinpaths(RelOptInfo *rel); -static List *TidqualFromRestrictinfo(List *relids, List *restrictinfo); -static bool isEvaluable(int varno, Node *node); -static Node *TidequalClause(int varno, Expr *node); -static List *TidqualFromExpr(int varno, Expr *expr); +static List *TidqualFromRestrictinfo(List *relids, List *restrictinfo); +static bool isEvaluable(int varno, Node *node); +static Node *TidequalClause(int varno, Expr *node); +static List *TidqualFromExpr(int varno, Expr *expr); static -bool isEvaluable(int varno, Node *node) +bool +isEvaluable(int varno, Node *node) { - List *lst; - Expr *expr; + List *lst; + Expr *expr; - if (IsA(node, Const)) return true; - if (IsA(node, Param)) return true; + if (IsA(node, Const)) + return true; + if (IsA(node, Param)) + return true; if (IsA(node, Var)) { - Var *var = (Var *)node; + Var *var = (Var *) node; if (var->varno == varno) return false; return true; } - if (!is_funcclause(node)) return false; - expr = (Expr *)node; - foreach (lst, expr->args) + if (!is_funcclause(node)) + return false; + expr = (Expr *) node; + foreach(lst, expr->args) { if (!isEvaluable(varno, lfirst(lst))) return false; @@ -72,53 +76,60 @@ bool isEvaluable(int varno, Node *node) /* * The 2nd parameter should be an opclause * Extract the right node if the opclause is CTID= .... - * or the left node if the opclause is ....=CTID + * or the left node if the opclause is ....=CTID */ static -Node *TidequalClause(int varno, Expr *node) +Node * +TidequalClause(int varno, Expr *node) { - Node *rnode = 0, *arg1, *arg2, *arg; - Oper *oper; - Var *var; - Const *aconst; - Param *param; - Expr *expr; + Node *rnode = 0, + *arg1, + *arg2, + *arg; + Oper *oper; + Var *var; + Const *aconst; + Param *param; + Expr *expr; - if (!node->oper) return rnode; - if (!node->args) return rnode; - if (length(node->args) != 2) return rnode; - oper = (Oper *) node->oper; + if (!node->oper) + return rnode; + if (!node->args) + return rnode; + if (length(node->args) != 2) + return rnode; + oper = (Oper *) node->oper; if (oper->opno != TIDEqualOperator) return rnode; arg1 = lfirst(node->args); arg2 = lsecond(node->args); - arg = (Node *)0; + arg = (Node *) 0; if (IsA(arg1, Var)) { var = (Var *) arg1; if (var->varno == varno && - var->varattno == SelfItemPointerAttributeNumber && - var->vartype == TIDOID) + var->varattno == SelfItemPointerAttributeNumber && + var->vartype == TIDOID) arg = arg2; else if (var->varnoold == varno && - var->varoattno == SelfItemPointerAttributeNumber && - var->vartype == TIDOID) + var->varoattno == SelfItemPointerAttributeNumber && + var->vartype == TIDOID) arg = arg2; } if ((!arg) && IsA(arg2, Var)) { var = (Var *) arg2; if (var->varno == varno && - var->varattno == SelfItemPointerAttributeNumber && - var->vartype == TIDOID) + var->varattno == SelfItemPointerAttributeNumber && + var->vartype == TIDOID) arg = arg1; } if (!arg) return rnode; switch (nodeTag(arg)) { - case T_Const: + case T_Const: aconst = (Const *) arg; if (aconst->consttype != TIDOID) return rnode; @@ -126,27 +137,29 @@ Node *TidequalClause(int varno, Expr *node) return rnode; rnode = arg; break; - case T_Param: + case T_Param: param = (Param *) arg; if (param->paramtype != TIDOID) return rnode; rnode = arg; break; - case T_Var: + case T_Var: var = (Var *) arg; if (var->varno == varno || - var->vartype != TIDOID) + var->vartype != TIDOID) return rnode; rnode = arg; break; - case T_Expr: + case T_Expr: expr = (Expr *) arg; - if (expr->typeOid != TIDOID) return rnode; - if (expr->opType != FUNC_EXPR) return rnode; - if (isEvaluable(varno, (Node *)expr)) + if (expr->typeOid != TIDOID) + return rnode; + if (expr->opType != FUNC_EXPR) + return rnode; + if (isEvaluable(varno, (Node *) expr)) rnode = arg; break; - default: + default: break; } return rnode; @@ -160,43 +173,43 @@ Node *TidequalClause(int varno, Expr *node) * When the expr node is an and_clause,we return the list of * CTID values if we could extract the CTID values from a member * node. - */ + */ static -List *TidqualFromExpr(int varno, Expr *expr) +List * +TidqualFromExpr(int varno, Expr *expr) { - List *rlst = NIL, *lst, *frtn; - Node *node = (Node *) expr, *rnode; + List *rlst = NIL, + *lst, + *frtn; + Node *node = (Node *) expr, + *rnode; if (is_opclause(node)) { rnode = TidequalClause(varno, expr); if (rnode) - { rlst = lcons(rnode, rlst); - } } else if (and_clause(node)) { - foreach (lst, expr->args) + foreach(lst, expr->args) { node = lfirst(lst); - if (!IsA(node, Expr)) + if (!IsA(node, Expr)) continue; - rlst = TidqualFromExpr(varno, (Expr *)node); + rlst = TidqualFromExpr(varno, (Expr *) node); if (rlst) break; } } else if (or_clause(node)) { - foreach (lst, expr->args) + foreach(lst, expr->args) { node = lfirst(lst); if (IsA(node, Expr) && - (frtn = TidqualFromExpr(varno, (Expr *)node)) ) - { + (frtn = TidqualFromExpr(varno, (Expr *) node))) rlst = nconc(rlst, frtn); - } else { if (rlst) @@ -207,24 +220,26 @@ List *TidqualFromExpr(int varno, Expr *expr) } } return rlst; -} +} static List * TidqualFromRestrictinfo(List *relids, List *restrictinfo) { - List *lst, *rlst = NIL; - int varno; - Node *node; - Expr *expr; + List *lst, + *rlst = NIL; + int varno; + Node *node; + Expr *expr; if (length(relids) != 1) return NIL; varno = lfirsti(relids); - foreach (lst, restrictinfo) + foreach(lst, restrictinfo) { node = lfirst(lst); - if (!IsA(node, RestrictInfo)) continue; - expr = ((RestrictInfo *)node)->clause; + if (!IsA(node, RestrictInfo)) + continue; + expr = ((RestrictInfo *) node)->clause; rlst = TidqualFromExpr(varno, expr); if (rlst) break; @@ -241,20 +256,20 @@ TidqualFromRestrictinfo(List *relids, List *restrictinfo) static void create_tidscan_joinpaths(RelOptInfo *rel) { - List *rlst = NIL, - *lst; + List *rlst = NIL, + *lst; - foreach (lst, rel->joininfo) + foreach(lst, rel->joininfo) { JoinInfo *joininfo = (JoinInfo *) lfirst(lst); - List *restinfo, - *tideval; + List *restinfo, + *tideval; restinfo = joininfo->jinfo_restrictinfo; tideval = TidqualFromRestrictinfo(rel->relids, restinfo); if (length(tideval) == 1) { - TidPath *pathnode = makeNode(TidPath); + TidPath *pathnode = makeNode(TidPath); pathnode->path.pathtype = T_TidScan; pathnode->path.parent = rel; @@ -278,9 +293,9 @@ create_tidscan_joinpaths(RelOptInfo *rel) void create_tidscan_paths(Query *root, RelOptInfo *rel) { - List *tideval = TidqualFromRestrictinfo(rel->relids, - rel->baserestrictinfo); - + List *tideval = TidqualFromRestrictinfo(rel->relids, + rel->baserestrictinfo); + if (tideval) add_path(rel, (Path *) create_tidscan_path(rel, tideval)); create_tidscan_joinpaths(rel); diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index 3fab7f08b87..9cd8a11159a 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.88 2000/04/04 01:21:47 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.89 2000/04/12 17:15:21 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -32,15 +32,15 @@ static List *switch_outer(List *clauses); -static int set_tlist_sort_info(List *tlist, List *pathkeys); +static int set_tlist_sort_info(List *tlist, List *pathkeys); static Scan *create_scan_node(Query *root, Path *best_path, List *tlist); static Join *create_join_node(Query *root, JoinPath *best_path, List *tlist); static SeqScan *create_seqscan_node(Path *best_path, List *tlist, List *scan_clauses); static IndexScan *create_indexscan_node(Query *root, IndexPath *best_path, - List *tlist, List *scan_clauses); + List *tlist, List *scan_clauses); static TidScan *create_tidscan_node(TidPath *best_path, List *tlist, - List *scan_clauses); + List *scan_clauses); static NestLoop *create_nestloop_node(NestPath *best_path, List *tlist, List *clauses, Plan *outer_node, List *outer_tlist, Plan *inner_node, List *inner_tlist); @@ -52,16 +52,16 @@ static HashJoin *create_hashjoin_node(HashPath *best_path, List *tlist, Plan *inner_node, List *inner_tlist); static List *fix_indxqual_references(List *indexquals, IndexPath *index_path); static List *fix_indxqual_sublist(List *indexqual, int baserelid, Oid relam, - Form_pg_index index); + Form_pg_index index); static Node *fix_indxqual_operand(Node *node, int baserelid, - Form_pg_index index, - Oid *opclass); + Form_pg_index index, + Oid *opclass); static IndexScan *make_indexscan(List *qptlist, List *qpqual, Index scanrelid, - List *indxid, List *indxqual, - List *indxqualorig, - ScanDirection indexscandir); + List *indxid, List *indxqual, + List *indxqualorig, + ScanDirection indexscandir); static TidScan *make_tidscan(List *qptlist, List *qpqual, Index scanrelid, - List *tideval); + List *tideval); static NestLoop *make_nestloop(List *qptlist, List *qpqual, Plan *lefttree, Plan *righttree); static HashJoin *make_hashjoin(List *tlist, List *qpqual, @@ -166,8 +166,8 @@ create_scan_node(Query *root, Path *best_path, List *tlist) case T_TidScan: node = (Scan *) create_tidscan_node((TidPath *) best_path, - tlist, - scan_clauses); + tlist, + scan_clauses); break; default: @@ -242,6 +242,7 @@ create_join_node(Query *root, JoinPath *best_path, List *tlist) } #ifdef NOT_USED + /* * * Expensive function pullups may have pulled local predicates * * into this path node. Put them in the qpqual of the plan node. * @@ -250,7 +251,7 @@ create_join_node(Query *root, JoinPath *best_path, List *tlist) if (get_loc_restrictinfo(best_path) != NIL) set_qpqual((Plan) retval, nconc(get_qpqual((Plan) retval), - get_actual_clauses(get_loc_restrictinfo(best_path)))); + get_actual_clauses(get_loc_restrictinfo(best_path)))); #endif return retval; @@ -345,17 +346,17 @@ create_indexscan_node(Query *root, * for lossy indices the indxqual predicates need to be double-checked * after the index fetches the best-guess tuples. * - * Since the indexquals were generated from the restriction clauses - * given by scan_clauses, there will normally be some duplications - * between the lists. We get rid of the duplicates, then add back - * if lossy. + * Since the indexquals were generated from the restriction clauses given + * by scan_clauses, there will normally be some duplications between + * the lists. We get rid of the duplicates, then add back if lossy. */ if (length(indxqual) > 1) { + /* * Build an expression representation of the indexqual, expanding - * the implicit OR and AND semantics of the first- and second-level - * lists. + * the implicit OR and AND semantics of the first- and + * second-level lists. */ List *orclauses = NIL; List *orclause; @@ -374,8 +375,11 @@ create_indexscan_node(Query *root, } else if (indxqual != NIL) { - /* Here, we can simply treat the first sublist as an independent - * set of qual expressions, since there is no top-level OR behavior. + + /* + * Here, we can simply treat the first sublist as an independent + * set of qual expressions, since there is no top-level OR + * behavior. */ List *indxqual_list = lfirst(indxqual); @@ -387,8 +391,9 @@ create_indexscan_node(Query *root, else qpqual = scan_clauses; - /* The executor needs a copy with the indexkey on the left of each clause - * and with index attr numbers substituted for table ones. + /* + * The executor needs a copy with the indexkey on the left of each + * clause and with index attr numbers substituted for table ones. */ fixed_indxqual = fix_indxqual_references(indxqual, best_path); @@ -410,11 +415,11 @@ create_indexscan_node(Query *root, static TidScan * make_tidscan(List *qptlist, List *qpqual, - Index scanrelid, + Index scanrelid, List *tideval) { - TidScan *node = makeNode(TidScan); - Plan *plan = &node->scan.plan; + TidScan *node = makeNode(TidScan); + Plan *plan = &node->scan.plan; /* cost should be inserted by caller */ plan->state = (EState *) NULL; @@ -423,7 +428,8 @@ make_tidscan(List *qptlist, plan->lefttree = NULL; plan->righttree = NULL; node->scan.scanrelid = scanrelid; - node->tideval = copyObject(tideval); /* XXX do we really need a copy? */ + node->tideval = copyObject(tideval); /* XXX do we really need a + * copy? */ node->needRescan = false; node->scan.scanstate = (CommonScanState *) NULL; @@ -438,8 +444,8 @@ make_tidscan(List *qptlist, static TidScan * create_tidscan_node(TidPath *best_path, List *tlist, List *scan_clauses) { - TidScan *scan_node; - Index scan_relid; + TidScan *scan_node; + Index scan_relid; /* there should be exactly one base rel involved... */ Assert(length(best_path->path.parent->relids) == 1); @@ -452,7 +458,7 @@ create_tidscan_node(TidPath *best_path, List *tlist, List *scan_clauses) best_path->tideval); if (best_path->unjoined_relids) - scan_node->needRescan = true; + scan_node->needRescan = true; copy_path_costsize(&scan_node->scan.plan, &best_path->path); @@ -467,7 +473,7 @@ create_tidscan_node(TidPath *best_path, List *tlist, List *scan_clauses) * once we have changed a Var node to refer to a subplan output rather than * the original relation, it is no longer equal() to an unmodified Var node * for the same var. So, we cannot easily compare reference-adjusted qual - * clauses to clauses that have not been adjusted. Fortunately, that + * clauses to clauses that have not been adjusted. Fortunately, that * doesn't seem to be necessary; all the decisions are made before we do * the reference adjustments. * @@ -493,6 +499,7 @@ create_nestloop_node(NestPath *best_path, if (IsA(inner_node, IndexScan)) { + /* * An index is being used to reduce the number of tuples scanned * in the inner relation. If there are join clauses being used @@ -522,12 +529,13 @@ create_nestloop_node(NestPath *best_path, { Index innerrel = innerscan->scan.scanrelid; - /* Remove redundant tests from my clauses, if possible. - * Note we must compare against indxqualorig not the "fixed" - * indxqual (which has index attnos instead of relation attnos, - * and may have been commuted as well). + /* + * Remove redundant tests from my clauses, if possible. Note + * we must compare against indxqualorig not the "fixed" + * indxqual (which has index attnos instead of relation + * attnos, and may have been commuted as well). */ - if (length(indxqualorig) == 1) /* single indexscan? */ + if (length(indxqualorig) == 1) /* single indexscan? */ clauses = set_difference(clauses, lfirst(indxqualorig)); /* only refs to outer vars get changed in the inner indexqual */ @@ -549,17 +557,20 @@ create_nestloop_node(NestPath *best_path, } else if (IsA(inner_node, TidScan)) { - List *inner_tideval = ((TidScan *) inner_node)->tideval; - TidScan *innerscan = (TidScan *) inner_node; + List *inner_tideval = ((TidScan *) inner_node)->tideval; + TidScan *innerscan = (TidScan *) inner_node; + ((TidScan *) inner_node)->tideval = join_references(inner_tideval, outer_tlist, inner_tlist, innerscan->scan.scanrelid); - } + } else if (IsA_Join(inner_node)) { + /* * Materialize the inner join for speed reasons. * * XXX It is probably *not* always fastest to materialize an inner - * join --- how can we estimate whether this is a good thing to do? + * join --- how can we estimate whether this is a good thing to + * do? */ inner_node = (Plan *) make_noname(inner_tlist, NIL, @@ -595,9 +606,9 @@ create_mergejoin_node(MergePath *best_path, mergeclauses = get_actual_clauses(best_path->path_mergeclauses); /* - * Remove the mergeclauses from the list of join qual clauses, - * leaving the list of quals that must be checked as qpquals. - * Set those clauses to contain INNER/OUTER var references. + * Remove the mergeclauses from the list of join qual clauses, leaving + * the list of quals that must be checked as qpquals. Set those + * clauses to contain INNER/OUTER var references. */ qpqual = join_references(set_difference(clauses, mergeclauses), outer_tlist, @@ -655,16 +666,16 @@ create_hashjoin_node(HashPath *best_path, /* * NOTE: there will always be exactly one hashclause in the list - * best_path->path_hashclauses (cf. hash_inner_and_outer()). - * We represent it as a list anyway, for convenience with routines - * that want to work on lists of clauses. + * best_path->path_hashclauses (cf. hash_inner_and_outer()). We + * represent it as a list anyway, for convenience with routines that + * want to work on lists of clauses. */ hashclauses = get_actual_clauses(best_path->path_hashclauses); /* - * Remove the hashclauses from the list of join qual clauses, - * leaving the list of quals that must be checked as qpquals. - * Set those clauses to contain INNER/OUTER var references. + * Remove the hashclauses from the list of join qual clauses, leaving + * the list of quals that must be checked as qpquals. Set those + * clauses to contain INNER/OUTER var references. */ qpqual = join_references(set_difference(clauses, hashclauses), outer_tlist, @@ -779,7 +790,7 @@ fix_indxqual_references(List *indexquals, IndexPath *index_path) * * For each qual clause, commute if needed to put the indexkey operand on the * left, and then change its varno. (We do not need to change the other side - * of the clause.) Also change the operator if necessary. + * of the clause.) Also change the operator if necessary. */ static List * fix_indxqual_sublist(List *indexqual, int baserelid, Oid relam, @@ -803,14 +814,16 @@ fix_indxqual_sublist(List *indexqual, int baserelid, Oid relam, length(clause->args) != 2) elog(ERROR, "fix_indxqual_sublist: indexqual clause is not binary opclause"); - /* Which side is the indexkey on? + /* + * Which side is the indexkey on? * * get_relattval sets flag&SEL_RIGHT if the indexkey is on the LEFT. */ get_relattval((Node *) clause, baserelid, &relid, &attno, &constval, &flag); - /* Make a copy that will become the fixed clause. + /* + * Make a copy that will become the fixed clause. * * We used to try to do a shallow copy here, but that fails if there * is a subplan in the arguments of the opclause. So just do a @@ -822,18 +835,19 @@ fix_indxqual_sublist(List *indexqual, int baserelid, Oid relam, if ((flag & SEL_RIGHT) == 0) CommuteClause(newclause); - /* Now, determine which index attribute this is, - * change the indexkey operand as needed, - * and get the index opclass. + /* + * Now, determine which index attribute this is, change the + * indexkey operand as needed, and get the index opclass. */ lfirst(newclause->args) = fix_indxqual_operand(lfirst(newclause->args), baserelid, index, &opclass); - /* Substitute the appropriate operator if the expression operator - * is merely binary-compatible with the index. This shouldn't fail, - * since indxpath.c found it before... + /* + * Substitute the appropriate operator if the expression operator + * is merely binary-compatible with the index. This shouldn't + * fail, since indxpath.c found it before... */ newopno = indexable_operator(newclause, opclass, relam, true); if (newopno == InvalidOid) @@ -861,12 +875,14 @@ fix_indxqual_operand(Node *node, int baserelid, Form_pg_index index, if (index->indkey[pos] == varatt) { Node *newnode = copyObject(node); + ((Var *) newnode)->varattno = pos + 1; *opclass = index->indclass[pos]; return newnode; } } } + /* * Oops, this Var isn't the indexkey! */ @@ -876,13 +892,13 @@ fix_indxqual_operand(Node *node, int baserelid, Form_pg_index index, /* * Else, it must be a func expression representing a functional index. * - * Currently, there is no need for us to do anything here for - * functional indexes. If nodeIndexscan.c sees a func clause as the left - * or right-hand toplevel operand of an indexqual, it assumes that that is - * a reference to the functional index's value and makes the appropriate - * substitution. (It would be cleaner to make the substitution here, I - * think --- suspect this issue if a join clause involving a function call - * misbehaves...) + * Currently, there is no need for us to do anything here for functional + * indexes. If nodeIndexscan.c sees a func clause as the left or + * right-hand toplevel operand of an indexqual, it assumes that that + * is a reference to the functional index's value and makes the + * appropriate substitution. (It would be cleaner to make the + * substitution here, I think --- suspect this issue if a join clause + * involving a function call misbehaves...) */ /* indclass[0] is the only class of a functional index */ @@ -915,6 +931,7 @@ switch_outer(List *clauses) Assert(op && IsA(op, Var)); if (var_is_outer(op)) { + /* * Duplicate just enough of the structure to allow commuting * the clause without changing the original list. Could use @@ -954,21 +971,21 @@ set_tlist_sort_info(List *tlist, List *pathkeys) foreach(i, pathkeys) { - List *keysublist = (List *) lfirst(i); - PathKeyItem *pathkey = NULL; - Resdom *resdom = NULL; - List *j; + List *keysublist = (List *) lfirst(i); + PathKeyItem *pathkey = NULL; + Resdom *resdom = NULL; + List *j; /* * We can sort by any one of the sort key items listed in this - * sublist. For now, we take the first one that corresponds to - * an available Var in the tlist. + * sublist. For now, we take the first one that corresponds to an + * available Var in the tlist. * * XXX if we have a choice, is there any way of figuring out which * might be cheapest to execute? (For example, int4lt is likely - * much cheaper to execute than numericlt, but both might appear in - * the same pathkey sublist...) Not clear that we ever will have - * a choice in practice, so it may not matter. + * much cheaper to execute than numericlt, but both might appear + * in the same pathkey sublist...) Not clear that we ever will + * have a choice in practice, so it may not matter. */ foreach(j, keysublist) { @@ -982,12 +999,12 @@ set_tlist_sort_info(List *tlist, List *pathkeys) elog(ERROR, "set_tlist_sort_info: cannot find tlist item to sort"); /* - * The resdom might be already marked as a sort key, if the pathkeys - * contain duplicate entries. (This can happen in scenarios where - * multiple mergejoinable clauses mention the same var, for example.) - * In that case the current pathkey is essentially a no-op, because - * only one value can be seen within any subgroup where it would be - * consulted. We can ignore it. + * The resdom might be already marked as a sort key, if the + * pathkeys contain duplicate entries. (This can happen in + * scenarios where multiple mergejoinable clauses mention the same + * var, for example.) In that case the current pathkey is + * essentially a no-op, because only one value can be seen within + * any subgroup where it would be consulted. We can ignore it. */ if (resdom->reskey == 0) { @@ -1195,7 +1212,9 @@ make_hash(List *tlist, Var *hashkey, Plan *lefttree) Plan *plan = &node->plan; copy_plan_costsize(plan, lefttree); - /* For plausibility, make startup & total costs equal total cost of + + /* + * For plausibility, make startup & total costs equal total cost of * input plan; this only affects EXPLAIN display not decisions. */ plan->startup_cost = plan->total_cost; @@ -1237,7 +1256,7 @@ make_sort(List *tlist, Oid nonameid, Plan *lefttree, int keycount) Plan *plan = &node->plan; Path sort_path; /* dummy for result of cost_sort */ - copy_plan_costsize(plan, lefttree); /* only care about copying size */ + copy_plan_costsize(plan, lefttree); /* only care about copying size */ cost_sort(&sort_path, NIL, lefttree->plan_rows, lefttree->plan_width); plan->startup_cost = sort_path.startup_cost + lefttree->total_cost; plan->total_cost = sort_path.total_cost + lefttree->total_cost; @@ -1262,9 +1281,11 @@ make_material(List *tlist, Plan *plan = &node->plan; copy_plan_costsize(plan, lefttree); - /* For plausibility, make startup & total costs equal total cost of - * input plan; this only affects EXPLAIN display not decisions. - * XXX shouldn't we charge some additional cost for materialization? + + /* + * For plausibility, make startup & total costs equal total cost of + * input plan; this only affects EXPLAIN display not decisions. XXX + * shouldn't we charge some additional cost for materialization? */ plan->startup_cost = plan->total_cost; plan->state = (EState *) NULL; @@ -1285,18 +1306,21 @@ make_agg(List *tlist, List *qual, Plan *lefttree) Plan *plan = &node->plan; copy_plan_costsize(plan, lefttree); + /* - * Charge one cpu_operator_cost per aggregate function per input tuple. + * Charge one cpu_operator_cost per aggregate function per input + * tuple. */ plan->total_cost += cpu_operator_cost * plan->plan_rows * (length(pull_agg_clause((Node *) tlist)) + length(pull_agg_clause((Node *) qual))); + /* * We will produce a single output tuple if the input is not a Group, * and a tuple per group otherwise. For now, estimate the number of - * groups as 10% of the number of tuples --- bogus, but how to do better? - * (Note we assume the input Group node is in "tuplePerGroup" mode, - * so it didn't reduce its row count already.) + * groups as 10% of the number of tuples --- bogus, but how to do + * better? (Note we assume the input Group node is in "tuplePerGroup" + * mode, so it didn't reduce its row count already.) */ if (IsA(lefttree, Group)) plan->plan_rows *= 0.1; @@ -1326,19 +1350,21 @@ make_group(List *tlist, Plan *plan = &node->plan; copy_plan_costsize(plan, lefttree); + /* - * Charge one cpu_operator_cost per comparison per input tuple. - * We assume all columns get compared at most of the tuples. + * Charge one cpu_operator_cost per comparison per input tuple. We + * assume all columns get compared at most of the tuples. */ plan->total_cost += cpu_operator_cost * plan->plan_rows * ngrp; + /* - * If tuplePerGroup (which is named exactly backwards) is true, - * we will return all the input tuples, so the input node's row count - * is OK. Otherwise, we'll return only one tuple from each group. - * For now, estimate the number of groups as 10% of the number of - * tuples --- bogus, but how to do better? + * If tuplePerGroup (which is named exactly backwards) is true, we + * will return all the input tuples, so the input node's row count is + * OK. Otherwise, we'll return only one tuple from each group. For + * now, estimate the number of groups as 10% of the number of tuples + * --- bogus, but how to do better? */ - if (! tuplePerGroup) + if (!tuplePerGroup) plan->plan_rows *= 0.1; plan->state = (EState *) NULL; @@ -1369,11 +1395,13 @@ make_unique(List *tlist, Plan *lefttree, List *distinctList) List *slitem; copy_plan_costsize(plan, lefttree); + /* - * Charge one cpu_operator_cost per comparison per input tuple. - * We assume all columns get compared at most of the tuples. + * Charge one cpu_operator_cost per comparison per input tuple. We + * assume all columns get compared at most of the tuples. */ plan->total_cost += cpu_operator_cost * plan->plan_rows * numCols; + /* * As for Group, we make the unsupported assumption that there will be * 10% as many tuples out as in. @@ -1388,14 +1416,17 @@ make_unique(List *tlist, Plan *lefttree, List *distinctList) node->nonameid = _NONAME_RELATION_ID_; node->keycount = 0; - /* convert SortClause list into array of attr indexes, as wanted by exec */ + /* + * convert SortClause list into array of attr indexes, as wanted by + * exec + */ Assert(numCols > 0); uniqColIdx = (AttrNumber *) palloc(sizeof(AttrNumber) * numCols); foreach(slitem, distinctList) { - SortClause *sortcl = (SortClause *) lfirst(slitem); - TargetEntry *tle = get_sortgroupclause_tle(sortcl, tlist); + SortClause *sortcl = (SortClause *) lfirst(slitem); + TargetEntry *tle = get_sortgroupclause_tle(sortcl, tlist); uniqColIdx[keyno++] = tle->resdom->resno; } diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index 6b6f3971719..207981b527f 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.45 2000/02/15 20:49:18 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.46 2000/04/12 17:15:21 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -30,7 +30,7 @@ static void add_restrict_and_join_to_rel(Query *root, Node *clause); static void add_join_info_to_rels(Query *root, RestrictInfo *restrictinfo, - Relids join_relids); + Relids join_relids); static void add_vars_to_targetlist(Query *root, List *vars); static void check_mergejoinable(RestrictInfo *restrictinfo); static void check_hashjoinable(RestrictInfo *restrictinfo); @@ -83,7 +83,7 @@ add_vars_to_targetlist(Query *root, List *vars) * * If we have a range variable in the FROM clause that does not appear * in the target list nor qualifications, we must add it to the base - * relation list so that it will be joined. For instance, "select f.x + * relation list so that it will be joined. For instance, "select f.x * from foo f, foo f2" is a join of f and f2. Note that if we have * "select foo.x from foo f", it also gets turned into a join (between * foo as foo and foo as f). @@ -106,13 +106,15 @@ add_missing_rels_to_query(Query *root) { RelOptInfo *rel = get_base_rel(root, varno); - /* If the rel isn't otherwise referenced, give it a dummy + /* + * If the rel isn't otherwise referenced, give it a dummy * targetlist consisting of its own OID. */ if (rel->targetlist == NIL) { Var *var = makeVar(varno, ObjectIdAttributeNumber, OIDOID, -1, 0); + add_var_to_tlist(rel, var); } } @@ -142,14 +144,14 @@ add_restrict_and_join_to_rels(Query *root, List *clauses) List *clause; foreach(clause, clauses) - add_restrict_and_join_to_rel(root, (Node*) lfirst(clause)); + add_restrict_and_join_to_rel(root, (Node *) lfirst(clause)); } /* * add_restrict_and_join_to_rel * Add clause information to either the 'RestrictInfo' or 'JoinInfo' field * (depending on whether the clause is a join) of each base relation - * mentioned in the clause. A RestrictInfo node is created and added to + * mentioned in the clause. A RestrictInfo node is created and added to * the appropriate list for each rel. Also, if the clause uses a * mergejoinable operator, enter the left- and right-side expressions * into the query's lists of equijoined vars. @@ -175,6 +177,7 @@ add_restrict_and_join_to_rel(Query *root, Node *clause) if (length(relids) == 1) { + /* * There is only one relation participating in 'clause', so * 'clause' must be a restriction clause for that relation. @@ -183,21 +186,24 @@ add_restrict_and_join_to_rel(Query *root, Node *clause) rel->baserestrictinfo = lcons(restrictinfo, rel->baserestrictinfo); + /* * Check for a "mergejoinable" clause even though it's not a join - * clause. This is so that we can recognize that "a.x = a.y" makes - * x and y eligible to be considered equal, even when they belong - * to the same rel. Without this, we would not recognize that - * "a.x = a.y AND a.x = b.z AND a.y = c.q" allows us to consider - * z and q equal after their rels are joined. + * clause. This is so that we can recognize that "a.x = a.y" + * makes x and y eligible to be considered equal, even when they + * belong to the same rel. Without this, we would not recognize + * that "a.x = a.y AND a.x = b.z AND a.y = c.q" allows us to + * consider z and q equal after their rels are joined. */ check_mergejoinable(restrictinfo); } else { + /* * 'clause' is a join clause, since there is more than one atom in - * the relid list. Set additional RestrictInfo fields for joining. + * the relid list. Set additional RestrictInfo fields for + * joining. * * We need the merge info whether or not mergejoin is enabled (for * constructing equijoined-var lists), but we don't bother setting @@ -206,16 +212,19 @@ add_restrict_and_join_to_rel(Query *root, Node *clause) check_mergejoinable(restrictinfo); if (enable_hashjoin) check_hashjoinable(restrictinfo); + /* - * Add clause to the join lists of all the relevant - * relations. (If, perchance, 'clause' contains NO vars, then - * nothing will happen...) + * Add clause to the join lists of all the relevant relations. + * (If, perchance, 'clause' contains NO vars, then nothing will + * happen...) */ add_join_info_to_rels(root, restrictinfo, relids); + /* - * Add vars used in the join clause to targetlists of member relations, - * so that they will be emitted by the plan nodes that scan those - * relations (else they won't be available at the join node!). + * Add vars used in the join clause to targetlists of member + * relations, so that they will be emitted by the plan nodes that + * scan those relations (else they won't be available at the join + * node!). */ add_vars_to_targetlist(root, vars); } @@ -267,7 +276,7 @@ add_join_info_to_rels(Query *root, RestrictInfo *restrictinfo, joininfo = find_joininfo_node(get_base_rel(root, cur_relid), unjoined_relids); joininfo->jinfo_restrictinfo = lcons(restrictinfo, - joininfo->jinfo_restrictinfo); + joininfo->jinfo_restrictinfo); } } @@ -296,16 +305,16 @@ check_mergejoinable(RestrictInfo *restrictinfo) leftOp, rightOp; - if (! is_opclause((Node *) clause)) + if (!is_opclause((Node *) clause)) return; left = get_leftop(clause); right = get_rightop(clause); /* caution: is_opclause accepts more than I do, so check it */ - if (! right) + if (!right) return; /* unary opclauses need not apply */ - if (!IsA(left, Var) || !IsA(right, Var)) + if (!IsA(left, Var) ||!IsA(right, Var)) return; opno = ((Oper *) clause->oper)->opno; @@ -339,16 +348,16 @@ check_hashjoinable(RestrictInfo *restrictinfo) *right; Oid opno; - if (! is_opclause((Node *) clause)) + if (!is_opclause((Node *) clause)) return; left = get_leftop(clause); right = get_rightop(clause); /* caution: is_opclause accepts more than I do, so check it */ - if (! right) + if (!right) return; /* unary opclauses need not apply */ - if (!IsA(left, Var) || !IsA(right, Var)) + if (!IsA(left, Var) ||!IsA(right, Var)) return; opno = ((Oper *) clause->oper)->opno; @@ -356,7 +365,5 @@ check_hashjoinable(RestrictInfo *restrictinfo) if (op_hashjoinable(opno, left->vartype, right->vartype)) - { restrictinfo->hashjoinoperator = opno; - } } diff --git a/src/backend/optimizer/plan/planmain.c b/src/backend/optimizer/plan/planmain.c index 4377359ddcc..0e05c945380 100644 --- a/src/backend/optimizer/plan/planmain.c +++ b/src/backend/optimizer/plan/planmain.c @@ -14,7 +14,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planmain.c,v 1.54 2000/03/24 21:40:43 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planmain.c,v 1.55 2000/04/12 17:15:22 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -31,7 +31,7 @@ static Plan *subplanner(Query *root, List *flat_tlist, List *qual, - double tuple_fraction); + double tuple_fraction); /*-------------------- @@ -55,12 +55,12 @@ static Plan *subplanner(Query *root, List *flat_tlist, List *qual, * Query field and not a passed parameter is that the low-level routines * in indxpath.c need to see it.) The pathkeys value passed to query_planner * has not yet been "canonicalized", since the necessary info does not get - * computed until subplanner() scans the qual clauses. We canonicalize it + * computed until subplanner() scans the qual clauses. We canonicalize it * inside subplanner() as soon as that task is done. The output value * will be in canonical form as well. * * tuple_fraction is interpreted as follows: - * 0 (or less): expect all tuples to be retrieved (normal case) + * 0 (or less): expect all tuples to be retrieved (normal case) * 0 < tuple_fraction < 1: expect the given fraction of tuples available * from the plan to be retrieved * tuple_fraction >= 1: tuple_fraction is the absolute number of tuples @@ -91,7 +91,7 @@ query_planner(Query *root, if (root->commandType != CMD_SELECT) elog(ERROR, "Empty range table for non-SELECT query"); - root->query_pathkeys = NIL; /* signal unordered result */ + root->query_pathkeys = NIL; /* signal unordered result */ /* Make childless Result node to evaluate given tlist. */ return (Plan *) make_result(tlist, (Node *) qual, (Plan *) NULL); @@ -115,8 +115,8 @@ query_planner(Query *root, * * All subplan nodes will have "flat" (var-only) tlists. * - * This implies that all expression evaluations are done at the root - * of the plan tree. Once upon a time there was code to try to push + * This implies that all expression evaluations are done at the root of + * the plan tree. Once upon a time there was code to try to push * expensive function calls down to lower plan nodes, but that's dead * code and has been for a long time... */ @@ -132,9 +132,10 @@ query_planner(Query *root, */ if (constant_qual) { + /* - * The result node will also be responsible for evaluating - * the originally requested tlist. + * The result node will also be responsible for evaluating the + * originally requested tlist. */ subplan = (Plan *) make_result(tlist, (Node *) constant_qual, @@ -142,9 +143,11 @@ query_planner(Query *root, } else { + /* * Replace the toplevel plan node's flattened target list with the - * targetlist given by my caller, so that expressions are evaluated. + * targetlist given by my caller, so that expressions are + * evaluated. */ subplan->targetlist = tlist; } @@ -180,8 +183,9 @@ subplanner(Query *root, * Initialize the targetlist and qualification, adding entries to * base_rel_list as relation references are found (e.g., in the * qualification, the targetlist, etc.). Restrict and join clauses - * are added to appropriate lists belonging to the mentioned relations, - * and we also build lists of equijoined keys for pathkey construction. + * are added to appropriate lists belonging to the mentioned + * relations, and we also build lists of equijoined keys for pathkey + * construction. */ root->base_rel_list = NIL; root->join_rel_list = NIL; @@ -192,9 +196,9 @@ subplanner(Query *root, add_missing_rels_to_query(root); /* - * We should now have all the pathkey equivalence sets built, - * so it's now possible to convert the requested query_pathkeys - * to canonical form. + * We should now have all the pathkey equivalence sets built, so it's + * now possible to convert the requested query_pathkeys to canonical + * form. */ root->query_pathkeys = canonicalize_pathkeys(root, root->query_pathkeys); @@ -203,20 +207,22 @@ subplanner(Query *root, */ final_rel = make_one_rel(root); - if (! final_rel) + if (!final_rel) { + /* * We expect to end up here for a trivial INSERT ... VALUES query - * (which will have a target relation, so it gets past query_planner's - * check for empty range table; but the target rel is unreferenced - * and not marked inJoinSet, so we find there is nothing to join). - * + * (which will have a target relation, so it gets past + * query_planner's check for empty range table; but the target rel + * is unreferenced and not marked inJoinSet, so we find there is + * nothing to join). + * * It's also possible to get here if the query was rewritten by the - * rule processor (creating rangetable entries not marked inJoinSet) - * but the rules either did nothing or were simplified to nothing - * by constant-expression folding. So, don't complain. + * rule processor (creating rangetable entries not marked + * inJoinSet) but the rules either did nothing or were simplified + * to nothing by constant-expression folding. So, don't complain. */ - root->query_pathkeys = NIL; /* signal unordered result */ + root->query_pathkeys = NIL; /* signal unordered result */ /* Make childless Result node to evaluate given tlist. */ return (Plan *) make_result(flat_tlist, (Node *) qual, (Plan *) NULL); @@ -246,16 +252,16 @@ subplanner(Query *root, #endif /* - * Now that we have an estimate of the final rel's size, we can convert - * a tuple_fraction specified as an absolute count (ie, a LIMIT option) - * into a fraction of the total tuples. + * Now that we have an estimate of the final rel's size, we can + * convert a tuple_fraction specified as an absolute count (ie, a + * LIMIT option) into a fraction of the total tuples. */ if (tuple_fraction >= 1.0) tuple_fraction /= final_rel->rows; /* * Determine the cheapest path, independently of any ordering - * considerations. We do, however, take into account whether the + * considerations. We do, however, take into account whether the * whole plan is expected to be evaluated or not. */ if (tuple_fraction <= 0.0 || tuple_fraction >= 1.0) @@ -271,8 +277,8 @@ subplanner(Query *root, /* * Select the best path and create a subplan to execute it. * - * If no special sort order is wanted, or if the cheapest path is - * already appropriately ordered, we use the cheapest path found above. + * If no special sort order is wanted, or if the cheapest path is already + * appropriately ordered, we use the cheapest path found above. */ if (root->query_pathkeys == NIL || pathkeys_contained_in(root->query_pathkeys, @@ -284,7 +290,8 @@ subplanner(Query *root, /* * Otherwise, look to see if we have an already-ordered path that is - * cheaper than doing an explicit sort on the cheapest-total-cost path. + * cheaper than doing an explicit sort on the cheapest-total-cost + * path. */ cheapestpath = final_rel->cheapest_total_path; presortedpath = @@ -310,11 +317,11 @@ subplanner(Query *root, } /* - * Nothing for it but to sort the cheapest-total-cost path --- but we let - * the caller do that. union_planner has to be able to add a sort node - * anyway, so no need for extra code here. (Furthermore, the given - * pathkeys might involve something we can't compute here, such as an - * aggregate function...) + * Nothing for it but to sort the cheapest-total-cost path --- but we + * let the caller do that. union_planner has to be able to add a sort + * node anyway, so no need for extra code here. (Furthermore, the + * given pathkeys might involve something we can't compute here, such + * as an aggregate function...) */ root->query_pathkeys = cheapestpath->pathkeys; return create_plan(root, cheapestpath); diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index b8871d5801e..a92d439ee52 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.78 2000/03/21 05:12:01 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.79 2000/04/12 17:15:22 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -38,10 +38,10 @@ static List *make_subplanTargetList(Query *parse, List *tlist, - AttrNumber **groupColIdx); + AttrNumber **groupColIdx); static Plan *make_groupplan(List *group_tlist, bool tuplePerGroup, - List *groupClause, AttrNumber *grpColIdx, - bool is_presorted, Plan *subplan); + List *groupClause, AttrNumber *grpColIdx, + bool is_presorted, Plan *subplan); static Plan *make_sortplan(List *tlist, List *sortcls, Plan *plannode); /***************************************************************************** @@ -64,7 +64,7 @@ planner(Query *parse) transformKeySetQuery(parse); /* primary planning entry point (may recurse for subplans) */ - result_plan = subquery_planner(parse, -1.0 /* default case */); + result_plan = subquery_planner(parse, -1.0 /* default case */ ); Assert(PlannerQueryLevel == 1); @@ -110,21 +110,22 @@ planner(Query *parse) Plan * subquery_planner(Query *parse, double tuple_fraction) { + /* * A HAVING clause without aggregates is equivalent to a WHERE clause - * (except it can only refer to grouped fields). If there are no - * aggs anywhere in the query, then we don't want to create an Agg - * plan node, so merge the HAVING condition into WHERE. (We used to + * (except it can only refer to grouped fields). If there are no aggs + * anywhere in the query, then we don't want to create an Agg plan + * node, so merge the HAVING condition into WHERE. (We used to * consider this an error condition, but it seems to be legal SQL.) */ - if (parse->havingQual != NULL && ! parse->hasAggs) + if (parse->havingQual != NULL && !parse->hasAggs) { if (parse->qual == NULL) parse->qual = parse->havingQual; else parse->qual = (Node *) make_andclause(lappend(lcons(parse->qual, NIL), - parse->havingQual)); + parse->havingQual)); parse->havingQual = NULL; } @@ -144,8 +145,8 @@ subquery_planner(Query *parse, double tuple_fraction) /* * Canonicalize the qual, and convert it to implicit-AND format. * - * XXX Is there any value in re-applying eval_const_expressions - * after canonicalize_qual? + * XXX Is there any value in re-applying eval_const_expressions after + * canonicalize_qual? */ parse->qual = (Node *) canonicalize_qual((Expr *) parse->qual, true); #ifdef OPTIMIZER_DEBUG @@ -169,15 +170,17 @@ subquery_planner(Query *parse, double tuple_fraction) if (parse->groupClause != NIL) { + /* - * Check for ungrouped variables passed to subplans. - * Note we do NOT do this for subplans in WHERE; it's legal - * there because WHERE is evaluated pre-GROUP. + * Check for ungrouped variables passed to subplans. Note we + * do NOT do this for subplans in WHERE; it's legal there + * because WHERE is evaluated pre-GROUP. * - * An interesting fine point: if we reassigned a HAVING qual - * into WHERE above, then we will accept references to ungrouped - * vars from subplans in the HAVING qual. This is not entirely - * consistent, but it doesn't seem particularly harmful... + * An interesting fine point: if we reassigned a HAVING qual into + * WHERE above, then we will accept references to ungrouped + * vars from subplans in the HAVING qual. This is not + * entirely consistent, but it doesn't seem particularly + * harmful... */ check_subplans_for_ungrouped_vars((Node *) parse->targetList, parse); @@ -218,8 +221,8 @@ subquery_planner(Query *parse, double tuple_fraction) * tuple_fraction is the fraction of tuples we expect will be retrieved * * tuple_fraction is interpreted as follows: - * < 0: determine fraction by inspection of query (normal case) - * 0: expect all tuples to be retrieved + * < 0: determine fraction by inspection of query (normal case) + * 0: expect all tuples to be retrieved * 0 < tuple_fraction < 1: expect the given fraction of tuples available * from the plan to be retrieved * tuple_fraction >= 1: tuple_fraction is the absolute number of tuples @@ -251,13 +254,18 @@ union_planner(Query *parse, parse->commandType, parse->resultRelation, parse->rtable); + /* - * We leave current_pathkeys NIL indicating we do not know sort order. - * Actually, for a normal UNION we have done an explicit sort; ought - * to change interface to plan_union_queries to pass that info back! + * We leave current_pathkeys NIL indicating we do not know sort + * order. Actually, for a normal UNION we have done an explicit + * sort; ought to change interface to plan_union_queries to pass + * that info back! */ - /* Calculate pathkeys that represent grouping/ordering requirements */ + /* + * Calculate pathkeys that represent grouping/ordering + * requirements + */ group_pathkeys = make_pathkeys_for_sortclauses(parse->groupClause, tlist); sort_pathkeys = make_pathkeys_for_sortclauses(parse->sortClause, @@ -280,13 +288,13 @@ union_planner(Query *parse, rt_index); /* - * Fix up outer target list. NOTE: unlike the case for non-inherited - * query, we pass the unfixed tlist to subplans, which do their own - * fixing. But we still want to fix the outer target list afterwards. - * I *think* this is correct --- doing the fix before recursing is - * definitely wrong, because preprocess_targetlist() will do the - * wrong thing if invoked twice on the same list. Maybe that is a bug? - * tgl 6/6/99 + * Fix up outer target list. NOTE: unlike the case for + * non-inherited query, we pass the unfixed tlist to subplans, + * which do their own fixing. But we still want to fix the outer + * target list afterwards. I *think* this is correct --- doing the + * fix before recursing is definitely wrong, because + * preprocess_targetlist() will do the wrong thing if invoked + * twice on the same list. Maybe that is a bug? tgl 6/6/99 */ tlist = preprocess_targetlist(tlist, parse->commandType, @@ -295,12 +303,16 @@ union_planner(Query *parse, if (parse->rowMark != NULL) elog(ERROR, "SELECT FOR UPDATE is not supported for inherit queries"); + /* - * We leave current_pathkeys NIL indicating we do not know sort order - * of the Append-ed results. + * We leave current_pathkeys NIL indicating we do not know sort + * order of the Append-ed results. */ - /* Calculate pathkeys that represent grouping/ordering requirements */ + /* + * Calculate pathkeys that represent grouping/ordering + * requirements + */ group_pathkeys = make_pathkeys_for_sortclauses(parse->groupClause, tlist); sort_pathkeys = make_pathkeys_for_sortclauses(parse->sortClause, @@ -358,7 +370,10 @@ union_planner(Query *parse, */ sub_tlist = make_subplanTargetList(parse, tlist, &groupColIdx); - /* Calculate pathkeys that represent grouping/ordering requirements */ + /* + * Calculate pathkeys that represent grouping/ordering + * requirements + */ group_pathkeys = make_pathkeys_for_sortclauses(parse->groupClause, tlist); sort_pathkeys = make_pathkeys_for_sortclauses(parse->sortClause, @@ -368,11 +383,12 @@ union_planner(Query *parse, * Figure out whether we need a sorted result from query_planner. * * If we have a GROUP BY clause, then we want a result sorted - * properly for grouping. Otherwise, if there is an ORDER BY clause, - * we want to sort by the ORDER BY clause. (Note: if we have both, - * and ORDER BY is a superset of GROUP BY, it would be tempting to - * request sort by ORDER BY --- but that might just leave us failing - * to exploit an available sort order at all. Needs more thought...) + * properly for grouping. Otherwise, if there is an ORDER BY + * clause, we want to sort by the ORDER BY clause. (Note: if we + * have both, and ORDER BY is a superset of GROUP BY, it would be + * tempting to request sort by ORDER BY --- but that might just + * leave us failing to exploit an available sort order at all. + * Needs more thought...) */ if (parse->groupClause) parse->query_pathkeys = group_pathkeys; @@ -382,15 +398,16 @@ union_planner(Query *parse, parse->query_pathkeys = NIL; /* - * Figure out whether we expect to retrieve all the tuples that the - * plan can generate, or to stop early due to a LIMIT or other - * factors. If the caller passed a value >= 0, believe that value, - * else do our own examination of the query context. + * Figure out whether we expect to retrieve all the tuples that + * the plan can generate, or to stop early due to a LIMIT or other + * factors. If the caller passed a value >= 0, believe that + * value, else do our own examination of the query context. */ if (tuple_fraction < 0.0) { /* Initial assumption is we need all the tuples */ tuple_fraction = 0.0; + /* * Check for a LIMIT clause. */ @@ -430,33 +447,37 @@ union_planner(Query *parse, } else { + /* - * COUNT is a PARAM ... don't know exactly what the limit - * will be, but for lack of a better idea assume 10% - * of the plan's result is wanted. + * COUNT is a PARAM ... don't know exactly what the + * limit will be, but for lack of a better idea assume + * 10% of the plan's result is wanted. */ tuple_fraction = 0.10; } } + /* * Check for a retrieve-into-portal, ie DECLARE CURSOR. * * We have no real idea how many tuples the user will ultimately - * FETCH from a cursor, but it seems a good bet that he doesn't - * want 'em all. Optimize for 10% retrieval (you gotta better - * number?) + * FETCH from a cursor, but it seems a good bet that he + * doesn't want 'em all. Optimize for 10% retrieval (you + * gotta better number?) */ if (parse->isPortal) tuple_fraction = 0.10; } + /* * Adjust tuple_fraction if we see that we are going to apply * grouping/aggregation/etc. This is not overridable by the - * caller, since it reflects plan actions that this routine - * will certainly take, not assumptions about context. + * caller, since it reflects plan actions that this routine will + * certainly take, not assumptions about context. */ if (parse->groupClause) { + /* * In GROUP BY mode, we have the little problem that we don't * really know how many input tuples will be needed to make a @@ -464,33 +485,42 @@ union_planner(Query *parse, * input count. For lack of a better idea, assume 25% of the * input data will be processed if there is any output limit. * However, if the caller gave us a fraction rather than an - * absolute count, we can keep using that fraction (which amounts - * to assuming that all the groups are about the same size). + * absolute count, we can keep using that fraction (which + * amounts to assuming that all the groups are about the same + * size). */ if (tuple_fraction >= 1.0) tuple_fraction = 0.25; + /* * If both GROUP BY and ORDER BY are specified, we will need * two levels of sort --- and, therefore, certainly need to * read all the input tuples --- unless ORDER BY is a subset * of GROUP BY. (Although we are comparing non-canonicalized * pathkeys here, it should be OK since they will both contain - * only single-element sublists at this point. See pathkeys.c.) + * only single-element sublists at this point. See + * pathkeys.c.) */ if (parse->groupClause && parse->sortClause && - ! pathkeys_contained_in(sort_pathkeys, group_pathkeys)) + !pathkeys_contained_in(sort_pathkeys, group_pathkeys)) tuple_fraction = 0.0; } else if (parse->hasAggs) { - /* Ungrouped aggregate will certainly want all the input tuples. */ + + /* + * Ungrouped aggregate will certainly want all the input + * tuples. + */ tuple_fraction = 0.0; } else if (parse->distinctClause) { + /* * SELECT DISTINCT, like GROUP, will absorb an unpredictable - * number of input tuples per output tuple. Handle the same way. + * number of input tuples per output tuple. Handle the same + * way. */ if (tuple_fraction >= 1.0) tuple_fraction = 0.25; @@ -502,14 +532,15 @@ union_planner(Query *parse, (List *) parse->qual, tuple_fraction); - /* query_planner returns actual sort order (which is not + /* + * query_planner returns actual sort order (which is not * necessarily what we requested) in query_pathkeys. */ current_pathkeys = parse->query_pathkeys; } /* query_planner returns NULL if it thinks plan is bogus */ - if (! result_plan) + if (!result_plan) elog(ERROR, "union_planner: failed to create plan"); /* @@ -539,9 +570,9 @@ union_planner(Query *parse, /* * If there are aggregates then the Group node should just return - * the same set of vars as the subplan did (but we can exclude - * any GROUP BY expressions). If there are no aggregates - * then the Group node had better compute the final tlist. + * the same set of vars as the subplan did (but we can exclude any + * GROUP BY expressions). If there are no aggregates then the + * Group node had better compute the final tlist. */ if (parse->hasAggs) group_tlist = flatten_tlist(result_plan->targetlist); @@ -549,8 +580,8 @@ union_planner(Query *parse, group_tlist = tlist; /* - * Figure out whether the path result is already ordered the way we - * need it --- if so, no need for an explicit sort step. + * Figure out whether the path result is already ordered the way + * we need it --- if so, no need for an explicit sort step. */ if (pathkeys_contained_in(group_pathkeys, current_pathkeys)) { @@ -559,7 +590,9 @@ union_planner(Query *parse, } else { - /* We will need to do an explicit sort by the GROUP BY clause. + + /* + * We will need to do an explicit sort by the GROUP BY clause. * make_groupplan will do the work, but set current_pathkeys * to indicate the resulting order. */ @@ -594,10 +627,8 @@ union_planner(Query *parse, */ if (parse->sortClause) { - if (! pathkeys_contained_in(sort_pathkeys, current_pathkeys)) - { + if (!pathkeys_contained_in(sort_pathkeys, current_pathkeys)) result_plan = make_sortplan(tlist, parse->sortClause, result_plan); - } } /* @@ -633,7 +664,7 @@ union_planner(Query *parse, * we want to pass this targetlist to the subplan: * a,b,c,d,a+b * where the a+b target will be used by the Sort/Group steps, and the - * other targets will be used for computing the final results. (In the + * other targets will be used for computing the final results. (In the * above example we could theoretically suppress the a and b targets and * use only a+b, but it's not really worth the trouble.) * @@ -675,8 +706,9 @@ make_subplanTargetList(Query *parse, /* * If grouping, create sub_tlist entries for all GROUP BY expressions - * (GROUP BY items that are simple Vars should be in the list already), - * and make an array showing where the group columns are in the sub_tlist. + * (GROUP BY items that are simple Vars should be in the list + * already), and make an array showing where the group columns are in + * the sub_tlist. */ numCols = length(parse->groupClause); if (numCols > 0) @@ -690,10 +722,10 @@ make_subplanTargetList(Query *parse, foreach(gl, parse->groupClause) { - GroupClause *grpcl = (GroupClause *) lfirst(gl); - Node *groupexpr = get_sortgroupclause_expr(grpcl, tlist); - TargetEntry *te = NULL; - List *sl; + GroupClause *grpcl = (GroupClause *) lfirst(gl); + Node *groupexpr = get_sortgroupclause_expr(grpcl, tlist); + TargetEntry *te = NULL; + List *sl; /* Find or make a matching sub_tlist entry */ foreach(sl, sub_tlist) @@ -702,7 +734,7 @@ make_subplanTargetList(Query *parse, if (equal(groupexpr, te->expr)) break; } - if (! sl) + if (!sl) { te = makeTargetEntry(makeResdom(length(sub_tlist) + 1, exprType(groupexpr), @@ -739,8 +771,9 @@ make_groupplan(List *group_tlist, { int numCols = length(groupClause); - if (! is_presorted) + if (!is_presorted) { + /* * The Sort node always just takes a copy of the subplan's tlist * plus ordering information. (This might seem inefficient if the @@ -755,14 +788,14 @@ make_groupplan(List *group_tlist, foreach(gl, groupClause) { - GroupClause *grpcl = (GroupClause *) lfirst(gl); - TargetEntry *te = nth(grpColIdx[keyno]-1, sort_tlist); - Resdom *resdom = te->resdom; + GroupClause *grpcl = (GroupClause *) lfirst(gl); + TargetEntry *te = nth(grpColIdx[keyno] - 1, sort_tlist); + Resdom *resdom = te->resdom; /* - * Check for the possibility of duplicate group-by clauses --- the - * parser should have removed 'em, but the Sort executor will get - * terribly confused if any get through! + * Check for the possibility of duplicate group-by clauses --- + * the parser should have removed 'em, but the Sort executor + * will get terribly confused if any get through! */ if (resdom->reskey == 0) { @@ -808,8 +841,8 @@ make_sortplan(List *tlist, List *sortcls, Plan *plannode) /* * Check for the possibility of duplicate order-by clauses --- the - * parser should have removed 'em, but the executor will get terribly - * confused if any get through! + * parser should have removed 'em, but the executor will get + * terribly confused if any get through! */ if (resdom->reskey == 0) { diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c index 756333e0059..a72fa0e74f0 100644 --- a/src/backend/optimizer/plan/setrefs.c +++ b/src/backend/optimizer/plan/setrefs.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.61 2000/04/04 01:21:47 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.62 2000/04/12 17:15:22 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -24,13 +24,15 @@ #include "optimizer/tlist.h" #include "optimizer/var.h" -typedef struct { +typedef struct +{ List *outer_tlist; List *inner_tlist; Index acceptable_rel; } join_references_context; -typedef struct { +typedef struct +{ Index subvarno; List *subplanTargetList; } replace_vars_with_subplan_refs_context; @@ -38,12 +40,12 @@ typedef struct { static void set_join_references(Join *join); static void set_uppernode_references(Plan *plan, Index subvarno); static Node *join_references_mutator(Node *node, - join_references_context *context); + join_references_context *context); static Node *replace_vars_with_subplan_refs(Node *node, - Index subvarno, - List *subplanTargetList); + Index subvarno, + List *subplanTargetList); static Node *replace_vars_with_subplan_refs_mutator(Node *node, - replace_vars_with_subplan_refs_context *context); + replace_vars_with_subplan_refs_context *context); static bool fix_opids_walker(Node *node, void *context); /***************************************************************************** @@ -56,7 +58,7 @@ static bool fix_opids_walker(Node *node, void *context); * set_plan_references * This is the final processing pass of the planner/optimizer. The plan * tree is complete; we just have to adjust some representational details - * for the convenience of the executor. We update Vars in upper plan nodes + * for the convenience of the executor. We update Vars in upper plan nodes * to refer to the outputs of their subplans, and we compute regproc OIDs * for operators (ie, we look up the function that implements each op). * We must also build lists of all the subplan nodes present in each @@ -74,7 +76,8 @@ set_plan_references(Plan *plan) if (plan == NULL) return; - /* We must rebuild the plan's list of subplan nodes, since we are + /* + * We must rebuild the plan's list of subplan nodes, since we are * copying/mutating its expression trees. */ plan->subPlan = NIL; @@ -92,10 +95,10 @@ set_plan_references(Plan *plan) fix_opids((Node *) ((IndexScan *) plan)->indxqualorig); plan->subPlan = nconc(plan->subPlan, - pull_subplans((Node *) ((IndexScan *) plan)->indxqual)); + pull_subplans((Node *) ((IndexScan *) plan)->indxqual)); plan->subPlan = nconc(plan->subPlan, - pull_subplans((Node *) ((IndexScan *) plan)->indxqualorig)); + pull_subplans((Node *) ((IndexScan *) plan)->indxqualorig)); break; case T_NestLoop: set_join_references((Join *) plan); @@ -105,24 +108,26 @@ set_plan_references(Plan *plan) fix_opids((Node *) ((MergeJoin *) plan)->mergeclauses); plan->subPlan = nconc(plan->subPlan, - pull_subplans((Node *) ((MergeJoin *) plan)->mergeclauses)); + pull_subplans((Node *) ((MergeJoin *) plan)->mergeclauses)); break; case T_HashJoin: set_join_references((Join *) plan); fix_opids((Node *) ((HashJoin *) plan)->hashclauses); plan->subPlan = nconc(plan->subPlan, - pull_subplans((Node *) ((HashJoin *) plan)->hashclauses)); + pull_subplans((Node *) ((HashJoin *) plan)->hashclauses)); break; case T_Material: case T_Sort: case T_Unique: case T_Hash: - /* These plan types don't actually bother to evaluate their + + /* + * These plan types don't actually bother to evaluate their * targetlists or quals (because they just return their * unmodified input tuples). The optimizer is lazy about - * creating really valid targetlists for them. Best to - * just leave the targetlist alone. + * creating really valid targetlists for them. Best to just + * leave the targetlist alone. */ break; case T_Agg: @@ -130,7 +135,9 @@ set_plan_references(Plan *plan) set_uppernode_references(plan, (Index) 0); break; case T_Result: - /* Result may or may not have a subplan; no need to fix up + + /* + * Result may or may not have a subplan; no need to fix up * subplan references if it hasn't got one... * * XXX why does Result use a different subvarno from Agg/Group? @@ -144,9 +151,7 @@ set_plan_references(Plan *plan) break; case T_Append: foreach(pl, ((Append *) plan)->appendplans) - { set_plan_references((Plan *) lfirst(pl)); - } break; case T_TidScan: /* nothing special */ @@ -158,8 +163,8 @@ set_plan_references(Plan *plan) } /* - * For all plan types, fix operators in targetlist and qual expressions, - * and find subplans therein. + * For all plan types, fix operators in targetlist and qual + * expressions, and find subplans therein. */ fix_opids((Node *) plan->targetlist); fix_opids((Node *) plan->qual); @@ -176,20 +181,21 @@ set_plan_references(Plan *plan) * NOTE: it is essential that we recurse into subplans AFTER we set * subplan references in this plan's tlist and quals. If we did the * reference-adjustments bottom-up, then we would fail to match this - * plan's var nodes against the already-modified nodes of the subplans. + * plan's var nodes against the already-modified nodes of the + * subplans. */ set_plan_references(plan->lefttree); set_plan_references(plan->righttree); foreach(pl, plan->initPlan) { - SubPlan *sp = (SubPlan *) lfirst(pl); + SubPlan *sp = (SubPlan *) lfirst(pl); Assert(IsA(sp, SubPlan)); set_plan_references(sp->plan); } foreach(pl, plan->subPlan) { - SubPlan *sp = (SubPlan *) lfirst(pl); + SubPlan *sp = (SubPlan *) lfirst(pl); Assert(IsA(sp, SubPlan)); set_plan_references(sp->plan); @@ -325,9 +331,10 @@ join_references_mutator(Node *node, newvar->varattno = resdom->resno; return (Node *) newvar; } + /* - * Var not in either tlist --- either raise an error, - * or return the Var unmodified. + * Var not in either tlist --- either raise an error, or return + * the Var unmodified. */ if (var->varno != context->acceptable_rel) elog(ERROR, "join_references: variable not in subplan target lists"); @@ -370,7 +377,7 @@ replace_vars_with_subplan_refs(Node *node, static Node * replace_vars_with_subplan_refs_mutator(Node *node, - replace_vars_with_subplan_refs_context *context) + replace_vars_with_subplan_refs_context *context) { if (node == NULL) return NULL; @@ -414,7 +421,7 @@ fix_opids(Node *node) } static bool -fix_opids_walker (Node *node, void *context) +fix_opids_walker(Node *node, void *context) { if (node == NULL) return false; diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c index b77d8b586f6..3493bfda245 100644 --- a/src/backend/optimizer/plan/subselect.c +++ b/src/backend/optimizer/plan/subselect.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/subselect.c,v 1.34 2000/04/04 01:21:47 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/subselect.c,v 1.35 2000/04/12 17:15:22 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -82,19 +82,19 @@ replace_var(Var *var) varlevel = PlannerQueryLevel - var->varlevelsup; /* - * If there's already a PlannerParamVar entry for this same Var, - * just use it. NOTE: in situations involving UNION or inheritance, - * it is possible for the same varno/varlevel to refer to different RTEs - * in different parts of the parsetree, so that different fields might - * end up sharing the same Param number. As long as we check the vartype - * as well, I believe that this sort of aliasing will cause no trouble. - * The correct field should get stored into the Param slot at execution - * in each part of the tree. + * If there's already a PlannerParamVar entry for this same Var, just + * use it. NOTE: in situations involving UNION or inheritance, it is + * possible for the same varno/varlevel to refer to different RTEs in + * different parts of the parsetree, so that different fields might + * end up sharing the same Param number. As long as we check the + * vartype as well, I believe that this sort of aliasing will cause no + * trouble. The correct field should get stored into the Param slot at + * execution in each part of the tree. */ i = 0; foreach(ppv, PlannerParamVar) { - Var *pvar = lfirst(ppv); + Var *pvar = lfirst(ppv); if (pvar->varno == var->varno && pvar->varattno == var->varattno && @@ -104,7 +104,7 @@ replace_var(Var *var) i++; } - if (! ppv) + if (!ppv) { /* Nope, so make a new one */ i = new_param(var, varlevel); @@ -137,23 +137,25 @@ make_subplan(SubLink *slink) PlannerQueryLevel++; /* we become child */ /* - * For an EXISTS subplan, tell lower-level planner to expect that - * only the first tuple will be retrieved. For ALL and ANY subplans, - * we will be able to stop evaluating if the test condition fails, - * so very often not all the tuples will be retrieved; for lack of a - * better idea, specify 50% retrieval. For EXPR and MULTIEXPR subplans, - * use default behavior (we're only expecting one row out, anyway). + * For an EXISTS subplan, tell lower-level planner to expect that only + * the first tuple will be retrieved. For ALL and ANY subplans, we + * will be able to stop evaluating if the test condition fails, so + * very often not all the tuples will be retrieved; for lack of a + * better idea, specify 50% retrieval. For EXPR and MULTIEXPR + * subplans, use default behavior (we're only expecting one row out, + * anyway). * * NOTE: if you change these numbers, also change cost_qual_eval_walker() * in path/costsize.c. * - * XXX If an ALL/ANY subplan is uncorrelated, we may decide to materialize - * its result below. In that case it would've been better to specify - * full retrieval. At present, however, we can only detect correlation - * or lack of it after we've made the subplan :-(. Perhaps detection - * of correlation should be done as a separate step. Meanwhile, we don't - * want to be too optimistic about the percentage of tuples retrieved, - * for fear of selecting a plan that's bad for the materialization case. + * XXX If an ALL/ANY subplan is uncorrelated, we may decide to + * materialize its result below. In that case it would've been better + * to specify full retrieval. At present, however, we can only detect + * correlation or lack of it after we've made the subplan :-(. Perhaps + * detection of correlation should be done as a separate step. + * Meanwhile, we don't want to be too optimistic about the percentage + * of tuples retrieved, for fear of selecting a plan that's bad for + * the materialization case. */ if (slink->subLinkType == EXISTS_SUBLINK) tuple_fraction = 1.0; /* just like a LIMIT 1 */ @@ -167,8 +169,8 @@ make_subplan(SubLink *slink) /* * Assign subPlan, extParam and locParam to plan nodes. At the moment, - * SS_finalize_plan doesn't handle initPlan-s and so we assign them - * to the topmost plan node and take care about its extParam too. + * SS_finalize_plan doesn't handle initPlan-s and so we assign them to + * the topmost plan node and take care about its extParam too. */ (void) SS_finalize_plan(plan); plan->initPlan = PlannerInitPlan; @@ -206,8 +208,8 @@ make_subplan(SubLink *slink) /* * Un-correlated or undirect correlated plans of EXISTS, EXPR, or - * MULTIEXPR types can be used as initPlans. For EXISTS or EXPR, - * we just produce a Param referring to the result of evaluating the + * MULTIEXPR types can be used as initPlans. For EXISTS or EXPR, we + * just produce a Param referring to the result of evaluating the * initPlan. For MULTIEXPR, we must build an AND or OR-clause of the * individual comparison operators, using the appropriate lefthand * side expressions and Params for the initPlan's target items. @@ -228,6 +230,7 @@ make_subplan(SubLink *slink) else if (node->parParam == NIL && slink->subLinkType == EXPR_SUBLINK) { TargetEntry *te = lfirst(plan->targetlist); + /* need a var node just to pass to new_param()... */ Var *var = makeVar(0, 0, te->resdom->restype, te->resdom->restypmod, 0); @@ -247,14 +250,15 @@ make_subplan(SubLink *slink) int i = 0; /* - * Convert oper list of Opers into a list of Exprs, using - * lefthand arguments and Params representing inside results. + * Convert oper list of Opers into a list of Exprs, using lefthand + * arguments and Params representing inside results. */ foreach(lst, slink->oper) { Oper *oper = (Oper *) lfirst(lst); Node *lefthand = nth(i, slink->lefthand); TargetEntry *te = nth(i, plan->targetlist); + /* need a var node just to pass to new_param()... */ Var *var = makeVar(0, 0, te->resdom->restype, te->resdom->restypmod, 0); @@ -273,7 +277,9 @@ make_subplan(SubLink *slink) tup = get_operator_tuple(oper->opno); Assert(HeapTupleIsValid(tup)); opform = (Form_pg_operator) GETSTRUCT(tup); - /* Note: we use make_operand in case runtime type conversion + + /* + * Note: we use make_operand in case runtime type conversion * function calls must be inserted for this operator! */ left = make_operand("", lefthand, @@ -304,15 +310,16 @@ make_subplan(SubLink *slink) int i = 0; /* - * We can't convert subplans of ALL_SUBLINK or ANY_SUBLINK types to - * initPlans, even when they are uncorrelated or undirect correlated, - * because we need to scan the output of the subplan for each outer - * tuple. However, we have the option to tack a MATERIAL node onto - * the top of an uncorrelated/undirect correlated subplan, which lets - * us do the work of evaluating the subplan only once. We do this - * if the subplan's top plan node is anything more complicated than - * a plain sequential scan, and we do it even for seqscan if the - * qual appears selective enough to eliminate many tuples. + * We can't convert subplans of ALL_SUBLINK or ANY_SUBLINK types + * to initPlans, even when they are uncorrelated or undirect + * correlated, because we need to scan the output of the subplan + * for each outer tuple. However, we have the option to tack a + * MATERIAL node onto the top of an uncorrelated/undirect + * correlated subplan, which lets us do the work of evaluating the + * subplan only once. We do this if the subplan's top plan node + * is anything more complicated than a plain sequential scan, and + * we do it even for seqscan if the qual appears selective enough + * to eliminate many tuples. */ if (node->parParam == NIL) { @@ -336,10 +343,12 @@ make_subplan(SubLink *slink) break; case T_Material: case T_Sort: - /* Don't add another Material node if there's one already, - * nor if the top node is a Sort, since Sort materializes - * its output anyway. (I doubt either case can happen in - * practice for a subplan, but...) + + /* + * Don't add another Material node if there's one + * already, nor if the top node is a Sort, since Sort + * materializes its output anyway. (I doubt either + * case can happen in practice for a subplan, but...) */ use_material = false; break; @@ -359,7 +368,7 @@ make_subplan(SubLink *slink) /* * Make expression of SUBPLAN type */ - expr->typeOid = BOOLOID; /* bogus, but we don't really care */ + expr->typeOid = BOOLOID;/* bogus, but we don't really care */ expr->opType = SUBPLAN_EXPR; expr->oper = (Node *) node; @@ -371,17 +380,20 @@ make_subplan(SubLink *slink) Var *var = nth(lfirsti(lst), PlannerParamVar); var = (Var *) copyObject(var); - /* Must fix absolute-level varlevelsup from the - * PlannerParamVar entry. But since var is at current - * subplan level, this is easy: + + /* + * Must fix absolute-level varlevelsup from the + * PlannerParamVar entry. But since var is at current subplan + * level, this is easy: */ var->varlevelsup = 0; args = lappend(args, var); } expr->args = args; + /* - * Convert oper list of Opers into a list of Exprs, using - * lefthand arguments and Consts representing inside results. + * Convert oper list of Opers into a list of Exprs, using lefthand + * arguments and Consts representing inside results. */ foreach(lst, slink->oper) { @@ -395,8 +407,8 @@ make_subplan(SubLink *slink) *right; /* - * XXX really ought to fill in constlen and constbyval correctly, - * but right now ExecEvalExpr won't look at them... + * XXX really ought to fill in constlen and constbyval + * correctly, but right now ExecEvalExpr won't look at them... */ con = makeConst(te->resdom->restype, 0, 0, true, 0, 0, 0); @@ -404,7 +416,9 @@ make_subplan(SubLink *slink) tup = get_operator_tuple(oper->opno); Assert(HeapTupleIsValid(tup)); opform = (Form_pg_operator) GETSTRUCT(tup); - /* Note: we use make_operand in case runtime type conversion + + /* + * Note: we use make_operand in case runtime type conversion * function calls must be inserted for this operator! */ left = make_operand("", lefthand, @@ -450,9 +464,10 @@ set_unioni(List *l1, List *l2) * check in make_subplan to see whether a subselect has any subselects. */ -typedef struct finalize_primnode_results { - List *subplans; /* List of subplans found in expr */ - List *paramids; /* List of PARAM_EXEC paramids found */ +typedef struct finalize_primnode_results +{ + List *subplans; /* List of subplans found in expr */ + List *paramids; /* List of PARAM_EXEC paramids found */ } finalize_primnode_results; static bool @@ -464,16 +479,16 @@ finalize_primnode(Node *node, finalize_primnode_results *results) { if (((Param *) node)->paramkind == PARAM_EXEC) { - int paramid = (int) ((Param *) node)->paramid; + int paramid = (int) ((Param *) node)->paramid; - if (! intMember(paramid, results->paramids)) + if (!intMember(paramid, results->paramids)) results->paramids = lconsi(paramid, results->paramids); } return false; /* no more to do here */ } if (is_subplan(node)) { - SubPlan *subplan = (SubPlan *) ((Expr *) node)->oper; + SubPlan *subplan = (SubPlan *) ((Expr *) node)->oper; List *lst; /* Add subplan to subplans list */ @@ -486,7 +501,7 @@ finalize_primnode(Node *node, finalize_primnode_results *results) /* note varlevelsup is absolute level number */ if (var->varlevelsup < PlannerQueryLevel && - ! intMember(paramid, results->paramids)) + !intMember(paramid, results->paramids)) results->paramids = lconsi(paramid, results->paramids); } /* fall through to recurse into subplan args */ @@ -533,7 +548,7 @@ Node * SS_process_sublinks(Node *expr) { /* No setup needed for tree walk, so away we go */ - return process_sublinks_mutator(expr, NULL); + return process_sublinks_mutator(expr, NULL); } static Node * @@ -543,25 +558,26 @@ process_sublinks_mutator(Node *node, void *context) return NULL; if (IsA(node, SubLink)) { - SubLink *sublink = (SubLink *) node; + SubLink *sublink = (SubLink *) node; - /* First, scan the lefthand-side expressions, if any. - * This is a tad klugy since we modify the input SubLink node, - * but that should be OK (make_subplan does it too!) + /* + * First, scan the lefthand-side expressions, if any. This is a + * tad klugy since we modify the input SubLink node, but that + * should be OK (make_subplan does it too!) */ sublink->lefthand = (List *) process_sublinks_mutator((Node *) sublink->lefthand, context); /* Now build the SubPlan node and make the expr to return */ return make_subplan(sublink); } + /* * Note that we will never see a SubPlan expression in the input - * (since this is the very routine that creates 'em to begin with). - * So the code in expression_tree_mutator() that might do - * inappropriate things with SubPlans or SubLinks will not be - * exercised. + * (since this is the very routine that creates 'em to begin with). So + * the code in expression_tree_mutator() that might do inappropriate + * things with SubPlans or SubLinks will not be exercised. */ - Assert(! is_subplan(node)); + Assert(!is_subplan(node)); return expression_tree_mutator(node, process_sublinks_mutator, @@ -581,12 +597,13 @@ SS_finalize_plan(Plan *plan) results.subplans = NIL; /* initialize lists to NIL */ results.paramids = NIL; + /* * When we call finalize_primnode, results.paramids lists are - * automatically merged together. But when recursing to self, - * we have to do it the hard way. We want the paramids list - * to include params in subplans as well as at this level. - * (We don't care about finding subplans of subplans, though.) + * automatically merged together. But when recursing to self, we have + * to do it the hard way. We want the paramids list to include params + * in subplans as well as at this level. (We don't care about finding + * subplans of subplans, though.) */ /* Find params and subplans in targetlist and qual */ @@ -604,13 +621,15 @@ SS_finalize_plan(Plan *plan) case T_Append: foreach(lst, ((Append *) plan)->appendplans) results.paramids = set_unioni(results.paramids, - SS_finalize_plan((Plan *) lfirst(lst))); + SS_finalize_plan((Plan *) lfirst(lst))); break; case T_IndexScan: finalize_primnode((Node *) ((IndexScan *) plan)->indxqual, &results); - /* we need not look at indxqualorig, since it will have the + + /* + * we need not look at indxqualorig, since it will have the * same param references as indxqual, and we aren't really * concerned yet about having a complete subplan list. */ @@ -633,7 +652,7 @@ SS_finalize_plan(Plan *plan) case T_TidScan: finalize_primnode((Node *) ((TidScan *) plan)->tideval, - &results); + &results); break; case T_Agg: diff --git a/src/backend/optimizer/prep/prepqual.c b/src/backend/optimizer/prep/prepqual.c index 5f92c545cce..fae694dc264 100644 --- a/src/backend/optimizer/prep/prepqual.c +++ b/src/backend/optimizer/prep/prepqual.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepqual.c,v 1.23 2000/02/27 19:45:44 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepqual.c,v 1.24 2000/04/12 17:15:23 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -33,7 +33,7 @@ static Expr *and_normalize(List *andlist); static Expr *qual_cleanup(Expr *qual); static List *remove_duplicates(List *list); static void count_bool_nodes(Expr *qual, double *nodes, - double *cnfnodes, double *dnfnodes); + double *cnfnodes, double *dnfnodes); /***************************************************************************** * @@ -71,7 +71,7 @@ static void count_bool_nodes(Expr *qual, double *nodes, * * If 'removeAndFlag' is true then it removes explicit AND at the top level, * producing a list of implicitly-ANDed conditions. Otherwise, a regular - * boolean expression is returned. Since most callers pass 'true', we + * boolean expression is returned. Since most callers pass 'true', we * prefer to declare the result as List *, not Expr *. * * XXX This code could be much smarter, at the cost of also being slower, @@ -95,12 +95,14 @@ canonicalize_qual(Expr *qual, bool removeAndFlag) if (qual == NULL) return NIL; - /* Flatten AND and OR groups throughout the tree. - * This improvement is always worthwhile, so do it unconditionally. + /* + * Flatten AND and OR groups throughout the tree. This improvement is + * always worthwhile, so do it unconditionally. */ qual = flatten_andors(qual); - /* Push down NOTs. We do this only in the top-level boolean + /* + * Push down NOTs. We do this only in the top-level boolean * expression, without examining arguments of operators/functions. * Even so, it might not be a win if we are unable to find negators * for all the operators involved; perhaps we should compare before- @@ -109,21 +111,24 @@ canonicalize_qual(Expr *qual, bool removeAndFlag) newqual = find_nots(qual); /* - * Choose whether to convert to CNF, or DNF, or leave well enough alone. + * Choose whether to convert to CNF, or DNF, or leave well enough + * alone. * * We make an approximate estimate of the number of bottom-level nodes * that will appear in the CNF and DNF forms of the query. */ count_bool_nodes(newqual, &nodes, &cnfnodes, &dnfnodes); + /* * First heuristic is to forget about *both* normal forms if there are * a huge number of terms in the qual clause. This would only happen - * with machine-generated queries, presumably; and most likely such - * a query is already in either CNF or DNF. + * with machine-generated queries, presumably; and most likely such a + * query is already in either CNF or DNF. */ cnfok = dnfok = true; if (nodes >= 500.0) cnfok = dnfok = false; + /* * Second heuristic is to forget about either CNF or DNF if it shows * unreasonable growth compared to the original form of the qual, @@ -134,15 +139,17 @@ canonicalize_qual(Expr *qual, bool removeAndFlag) cnfok = false; if (dnfnodes >= 4.0 * nodes) dnfok = false; + /* - * Third heuristic is to prefer DNF if top level is already an OR, - * and only one relation is mentioned, and DNF is no larger than - * the CNF representation. (Pretty shaky; can we improve on this?) + * Third heuristic is to prefer DNF if top level is already an OR, and + * only one relation is mentioned, and DNF is no larger than the CNF + * representation. (Pretty shaky; can we improve on this?) */ if (cnfok && dnfok && dnfnodes <= cnfnodes && or_clause((Node *) newqual) && NumRelids((Node *) newqual) == 1) cnfok = false; + /* * Otherwise, we prefer CNF. * @@ -150,20 +157,26 @@ canonicalize_qual(Expr *qual, bool removeAndFlag) */ if (cnfok) { - /* Normalize into conjunctive normal form, and clean up the result. */ + + /* + * Normalize into conjunctive normal form, and clean up the + * result. + */ newqual = qual_cleanup(find_ors(newqual)); } else if (dnfok) { - /* Normalize into disjunctive normal form, and clean up the result. */ + + /* + * Normalize into disjunctive normal form, and clean up the + * result. + */ newqual = qual_cleanup(find_ands(newqual)); } /* Convert to implicit-AND list if requested */ if (removeAndFlag) - { newqual = (Expr *) make_ands_implicit(newqual); - } return (List *) newqual; } @@ -177,7 +190,7 @@ canonicalize_qual(Expr *qual, bool removeAndFlag) * * If 'removeAndFlag' is true then it removes explicit AND at the top level, * producing a list of implicitly-ANDed conditions. Otherwise, a regular - * boolean expression is returned. Since most callers pass 'true', we + * boolean expression is returned. Since most callers pass 'true', we * prefer to declare the result as List *, not Expr *. */ List * @@ -188,11 +201,14 @@ cnfify(Expr *qual, bool removeAndFlag) if (qual == NULL) return NIL; - /* Flatten AND and OR groups throughout the tree. - * This improvement is always worthwhile. + /* + * Flatten AND and OR groups throughout the tree. This improvement is + * always worthwhile. */ newqual = flatten_andors(qual); - /* Push down NOTs. We do this only in the top-level boolean + + /* + * Push down NOTs. We do this only in the top-level boolean * expression, without examining arguments of operators/functions. */ newqual = find_nots(newqual); @@ -202,9 +218,7 @@ cnfify(Expr *qual, bool removeAndFlag) newqual = qual_cleanup(newqual); if (removeAndFlag) - { newqual = (Expr *) make_ands_implicit(newqual); - } return (List *) newqual; } @@ -227,11 +241,14 @@ dnfify(Expr *qual) if (qual == NULL) return NULL; - /* Flatten AND and OR groups throughout the tree. - * This improvement is always worthwhile. + /* + * Flatten AND and OR groups throughout the tree. This improvement is + * always worthwhile. */ newqual = flatten_andors(qual); - /* Push down NOTs. We do this only in the top-level boolean + + /* + * Push down NOTs. We do this only in the top-level boolean * expression, without examining arguments of operators/functions. */ newqual = find_nots(newqual); @@ -280,13 +297,13 @@ flatten_andors(Expr *qual) foreach(arg, qual->args) { - Expr *subexpr = flatten_andors((Expr *) lfirst(arg)); + Expr *subexpr = flatten_andors((Expr *) lfirst(arg)); /* - * Note: we can destructively nconc the subexpression's arglist - * because we know the recursive invocation of flatten_andors - * will have built a new arglist not shared with any other expr. - * Otherwise we'd need a listCopy here. + * Note: we can destructively nconc the subexpression's + * arglist because we know the recursive invocation of + * flatten_andors will have built a new arglist not shared + * with any other expr. Otherwise we'd need a listCopy here. */ if (and_clause((Node *) subexpr)) out_list = nconc(out_list, subexpr->args); @@ -302,13 +319,13 @@ flatten_andors(Expr *qual) foreach(arg, qual->args) { - Expr *subexpr = flatten_andors((Expr *) lfirst(arg)); + Expr *subexpr = flatten_andors((Expr *) lfirst(arg)); /* - * Note: we can destructively nconc the subexpression's arglist - * because we know the recursive invocation of flatten_andors - * will have built a new arglist not shared with any other expr. - * Otherwise we'd need a listCopy here. + * Note: we can destructively nconc the subexpression's + * arglist because we know the recursive invocation of + * flatten_andors will have built a new arglist not shared + * with any other expr. Otherwise we'd need a listCopy here. */ if (or_clause((Node *) subexpr)) out_list = nconc(out_list, subexpr->args); @@ -354,13 +371,13 @@ pull_ors(List *orlist) foreach(arg, orlist) { - Expr *subexpr = (Expr *) lfirst(arg); + Expr *subexpr = (Expr *) lfirst(arg); /* * Note: we can destructively nconc the subexpression's arglist - * because we know the recursive invocation of pull_ors - * will have built a new arglist not shared with any other expr. - * Otherwise we'd need a listCopy here. + * because we know the recursive invocation of pull_ors will have + * built a new arglist not shared with any other expr. Otherwise + * we'd need a listCopy here. */ if (or_clause((Node *) subexpr)) out_list = nconc(out_list, pull_ors(subexpr->args)); @@ -385,13 +402,13 @@ pull_ands(List *andlist) foreach(arg, andlist) { - Expr *subexpr = (Expr *) lfirst(arg); + Expr *subexpr = (Expr *) lfirst(arg); /* * Note: we can destructively nconc the subexpression's arglist - * because we know the recursive invocation of pull_ands - * will have built a new arglist not shared with any other expr. - * Otherwise we'd need a listCopy here. + * because we know the recursive invocation of pull_ands will have + * built a new arglist not shared with any other expr. Otherwise + * we'd need a listCopy here. */ if (and_clause((Node *) subexpr)) out_list = nconc(out_list, pull_ands(subexpr->args)); @@ -407,7 +424,7 @@ pull_ands(List *andlist) * For 'NOT' clauses, apply push_not() to try to push down the 'NOT'. * For all other clause types, simply recurse. * - * Returns the modified qualification. AND/OR flatness is preserved. + * Returns the modified qualification. AND/OR flatness is preserved. */ static Expr * find_nots(Expr *qual) @@ -468,7 +485,8 @@ static Expr * push_nots(Expr *qual) { if (qual == NULL) - return make_notclause(qual); /* XXX is this right? Or possible? */ + return make_notclause(qual); /* XXX is this right? Or + * possible? */ /* * Negate an operator clause if possible: ("NOT" (< A B)) => (> A B) @@ -486,6 +504,7 @@ push_nots(Expr *qual) InvalidOid, oper->opresulttype, 0, NULL); + return make_opclause(op, get_leftop(qual), get_rightop(qual)); } else @@ -496,7 +515,7 @@ push_nots(Expr *qual) /*-------------------- * Apply DeMorgan's Laws: * ("NOT" ("AND" A B)) => ("OR" ("NOT" A) ("NOT" B)) - * ("NOT" ("OR" A B)) => ("AND" ("NOT" A) ("NOT" B)) + * ("NOT" ("OR" A B)) => ("AND" ("NOT" A) ("NOT" B)) * i.e., swap AND for OR and negate all the subclauses. *-------------------- */ @@ -518,6 +537,7 @@ push_nots(Expr *qual) } else if (not_clause((Node *) qual)) { + /* * Another 'not' cancels this 'not', so eliminate the 'not' and * stop negating this branch. But search the subexpression for @@ -527,6 +547,7 @@ push_nots(Expr *qual) } else { + /* * We don't know how to negate anything else, place a 'not' at * this level. @@ -544,7 +565,7 @@ push_nots(Expr *qual) * Note that 'or' clauses will always be turned into 'and' clauses * if they contain any 'and' subclauses. * - * Returns the modified qualification. AND/OR flatness is preserved. + * Returns the modified qualification. AND/OR flatness is preserved. */ static Expr * find_ors(Expr *qual) @@ -601,17 +622,17 @@ or_normalize(List *orlist) return lfirst(orlist); /* single-expression OR (can this happen?) */ /* - * If we have a choice of AND clauses, pick the one with the - * most subclauses. Because we initialized num_subclauses = 1, - * any AND clauses with only one arg will be ignored as useless. + * If we have a choice of AND clauses, pick the one with the most + * subclauses. Because we initialized num_subclauses = 1, any AND + * clauses with only one arg will be ignored as useless. */ foreach(temp, orlist) { - Expr *clause = lfirst(temp); + Expr *clause = lfirst(temp); if (and_clause((Node *) clause)) { - int nclauses = length(clause->args); + int nclauses = length(clause->args); if (nclauses > num_subclauses) { @@ -622,12 +643,13 @@ or_normalize(List *orlist) } /* if there's no suitable AND clause, we can't transform the OR */ - if (! distributable) + if (!distributable) return make_orclause(orlist); - /* Caution: lremove destructively modifies the input orlist. - * This should be OK, since or_normalize is only called with - * freshly constructed lists that are not referenced elsewhere. + /* + * Caution: lremove destructively modifies the input orlist. This + * should be OK, since or_normalize is only called with freshly + * constructed lists that are not referenced elsewhere. */ orlist = lremove(distributable, orlist); @@ -635,11 +657,12 @@ or_normalize(List *orlist) { Expr *andclause = lfirst(temp); - /* pull_ors is needed here in case andclause has a top-level OR. - * Then we recursively apply or_normalize, since there might - * be an AND subclause in the resulting OR-list. - * Note: we rely on pull_ors to build a fresh list, - * and not damage the given orlist. + /* + * pull_ors is needed here in case andclause has a top-level OR. + * Then we recursively apply or_normalize, since there might be an + * AND subclause in the resulting OR-list. Note: we rely on + * pull_ors to build a fresh list, and not damage the given + * orlist. */ andclause = or_normalize(pull_ors(lcons(andclause, orlist))); andclauses = lappend(andclauses, andclause); @@ -658,7 +681,7 @@ or_normalize(List *orlist) * Note that 'and' clauses will always be turned into 'or' clauses * if they contain any 'or' subclauses. * - * Returns the modified qualification. AND/OR flatness is preserved. + * Returns the modified qualification. AND/OR flatness is preserved. */ static Expr * find_ands(Expr *qual) @@ -712,20 +735,21 @@ and_normalize(List *andlist) if (andlist == NIL) return NULL; /* probably can't happen */ if (lnext(andlist) == NIL) - return lfirst(andlist); /* single-expression AND (can this happen?) */ + return lfirst(andlist); /* single-expression AND (can this + * happen?) */ /* - * If we have a choice of OR clauses, pick the one with the - * most subclauses. Because we initialized num_subclauses = 1, - * any OR clauses with only one arg will be ignored as useless. + * If we have a choice of OR clauses, pick the one with the most + * subclauses. Because we initialized num_subclauses = 1, any OR + * clauses with only one arg will be ignored as useless. */ foreach(temp, andlist) { - Expr *clause = lfirst(temp); + Expr *clause = lfirst(temp); if (or_clause((Node *) clause)) { - int nclauses = length(clause->args); + int nclauses = length(clause->args); if (nclauses > num_subclauses) { @@ -736,12 +760,13 @@ and_normalize(List *andlist) } /* if there's no suitable OR clause, we can't transform the AND */ - if (! distributable) + if (!distributable) return make_andclause(andlist); - /* Caution: lremove destructively modifies the input andlist. - * This should be OK, since and_normalize is only called with - * freshly constructed lists that are not referenced elsewhere. + /* + * Caution: lremove destructively modifies the input andlist. This + * should be OK, since and_normalize is only called with freshly + * constructed lists that are not referenced elsewhere. */ andlist = lremove(distributable, andlist); @@ -749,11 +774,12 @@ and_normalize(List *andlist) { Expr *orclause = lfirst(temp); - /* pull_ands is needed here in case orclause has a top-level AND. - * Then we recursively apply and_normalize, since there might - * be an OR subclause in the resulting AND-list. - * Note: we rely on pull_ands to build a fresh list, - * and not damage the given andlist. + /* + * pull_ands is needed here in case orclause has a top-level AND. + * Then we recursively apply and_normalize, since there might be + * an OR subclause in the resulting AND-list. Note: we rely on + * pull_ands to build a fresh list, and not damage the given + * andlist. */ orclause = and_normalize(pull_ands(lcons(orclause, andlist))); orclauses = lappend(orclauses, orclause); @@ -767,7 +793,7 @@ and_normalize(List *andlist) * qual_cleanup * Fix up a qualification by removing duplicate entries (which could be * created during normalization, if identical subexpressions from different - * parts of the tree are brought together). Also, check for AND and OR + * parts of the tree are brought together). Also, check for AND and OR * clauses with only one remaining subexpression, and simplify. * * Returns the modified qualification. @@ -828,7 +854,7 @@ remove_duplicates(List *list) foreach(i, list) { - if (! member(lfirst(i), result)) + if (!member(lfirst(i), result)) result = lappend(result, lfirst(i)); } return result; @@ -855,7 +881,9 @@ count_bool_nodes(Expr *qual, double *dnfnodes) { List *temp; - double subnodes, subcnfnodes, subdnfnodes; + double subnodes, + subcnfnodes, + subdnfnodes; if (and_clause((Node *) qual)) { @@ -864,13 +892,15 @@ count_bool_nodes(Expr *qual, foreach(temp, qual->args) { - count_bool_nodes(lfirst(temp), + count_bool_nodes(lfirst(temp), &subnodes, &subcnfnodes, &subdnfnodes); *nodes += subnodes; *cnfnodes += subcnfnodes; *dnfnodes *= subdnfnodes; } - /* we could get dnfnodes < cnfnodes here, if all the sub-nodes are + + /* + * we could get dnfnodes < cnfnodes here, if all the sub-nodes are * simple ones with count 1. Make sure dnfnodes isn't too small. */ if (*dnfnodes < *cnfnodes) @@ -883,13 +913,15 @@ count_bool_nodes(Expr *qual, foreach(temp, qual->args) { - count_bool_nodes(lfirst(temp), + count_bool_nodes(lfirst(temp), &subnodes, &subcnfnodes, &subdnfnodes); *nodes += subnodes; *cnfnodes *= subcnfnodes; *dnfnodes += subdnfnodes; } - /* we could get cnfnodes < dnfnodes here, if all the sub-nodes are + + /* + * we could get cnfnodes < dnfnodes here, if all the sub-nodes are * simple ones with count 1. Make sure cnfnodes isn't too small. */ if (*cnfnodes < *dnfnodes) diff --git a/src/backend/optimizer/prep/preptlist.c b/src/backend/optimizer/prep/preptlist.c index 22ed6f418f7..22f06bb61a9 100644 --- a/src/backend/optimizer/prep/preptlist.c +++ b/src/backend/optimizer/prep/preptlist.c @@ -4,7 +4,7 @@ * Routines to preprocess the parse tree target list * * This module takes care of altering the query targetlist as needed for - * INSERT, UPDATE, and DELETE queries. For INSERT and UPDATE queries, + * INSERT, UPDATE, and DELETE queries. For INSERT and UPDATE queries, * the targetlist must contain an entry for each attribute of the target * relation in the correct order. For both UPDATE and DELETE queries, * we need a junk targetlist entry holding the CTID attribute --- the @@ -15,7 +15,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/preptlist.c,v 1.35 2000/03/09 05:00:24 inoue Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/preptlist.c,v 1.36 2000/04/12 17:15:23 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -31,7 +31,7 @@ static List *expand_targetlist(List *tlist, int command_type, - Index result_relation, List *range_table); + Index result_relation, List *range_table); /* @@ -46,6 +46,7 @@ preprocess_targetlist(List *tlist, Index result_relation, List *range_table) { + /* * for heap_formtuple to work, the targetlist must match the exact * order of the attributes. We also need to fill in any missing @@ -56,11 +57,11 @@ preprocess_targetlist(List *tlist, result_relation, range_table); /* - * for "update" and "delete" queries, add ctid of the result - * relation into the target list so that the ctid will propagate - * through execution and ExecutePlan() will be able to identify - * the right tuple to replace or delete. This extra field is - * marked "junk" so that it is not stored back into the tuple. + * for "update" and "delete" queries, add ctid of the result relation + * into the target list so that the ctid will propagate through + * execution and ExecutePlan() will be able to identify the right + * tuple to replace or delete. This extra field is marked "junk" so + * that it is not stored back into the tuple. */ if (command_type == CMD_UPDATE || command_type == CMD_DELETE) { @@ -78,7 +79,8 @@ preprocess_targetlist(List *tlist, var = makeVar(result_relation, SelfItemPointerAttributeNumber, TIDOID, -1, 0); - /* For an UPDATE, expand_targetlist already created a fresh tlist. + /* + * For an UPDATE, expand_targetlist already created a fresh tlist. * For DELETE, better do a listCopy so that we don't destructively * modify the original tlist (is this really necessary?). */ @@ -117,11 +119,11 @@ expand_targetlist(List *tlist, int command_type, List *temp; /* - * Keep a map of which tlist items we have transferred to new list. - * +1 here keeps palloc from complaining if old_tlist_len=0. + * Keep a map of which tlist items we have transferred to new list. +1 + * here keeps palloc from complaining if old_tlist_len=0. */ - tlistentry_used = (bool *) palloc((old_tlist_len+1) * sizeof(bool)); - memset(tlistentry_used, 0, (old_tlist_len+1) * sizeof(bool)); + tlistentry_used = (bool *) palloc((old_tlist_len + 1) * sizeof(bool)); + memset(tlistentry_used, 0, (old_tlist_len + 1) * sizeof(bool)); /* * Scan the tuple description in the relation's relcache entry to make @@ -133,9 +135,9 @@ expand_targetlist(List *tlist, int command_type, for (attrno = 1; attrno <= numattrs; attrno++) { - Form_pg_attribute att_tup = rel->rd_att->attrs[attrno-1]; - char *attrname = NameStr(att_tup->attname); - TargetEntry *new_tle = NULL; + Form_pg_attribute att_tup = rel->rd_att->attrs[attrno - 1]; + char *attrname = NameStr(att_tup->attname); + TargetEntry *new_tle = NULL; /* * We match targetlist entries to attributes using the resname. @@ -143,22 +145,22 @@ expand_targetlist(List *tlist, int command_type, old_tlist_index = 0; foreach(temp, tlist) { - TargetEntry *old_tle = (TargetEntry *) lfirst(temp); - Resdom *resdom = old_tle->resdom; + TargetEntry *old_tle = (TargetEntry *) lfirst(temp); + Resdom *resdom = old_tle->resdom; - if (! tlistentry_used[old_tlist_index] && + if (!tlistentry_used[old_tlist_index] && strcmp(resdom->resname, attrname) == 0 && - ! resdom->resjunk) + !resdom->resjunk) { + /* * We can recycle the old TLE+resdom if right resno; else - * make a new one to avoid modifying the old tlist structure. - * (Is preserving old tlist actually necessary?) + * make a new one to avoid modifying the old tlist + * structure. (Is preserving old tlist actually + * necessary?) */ if (resdom->resno == attrno) - { new_tle = old_tle; - } else { resdom = (Resdom *) copyObject((Node *) resdom); @@ -173,14 +175,15 @@ expand_targetlist(List *tlist, int command_type, if (new_tle == NULL) { + /* * Didn't find a matching tlist entry, so make one. * - * For INSERT, generate a constant of the default value for - * the attribute type, or NULL if no default value. + * For INSERT, generate a constant of the default value for the + * attribute type, or NULL if no default value. * - * For UPDATE, generate a Var reference to the existing value - * of the attribute, so that it gets copied to the new tuple. + * For UPDATE, generate a Var reference to the existing value of + * the attribute, so that it gets copied to the new tuple. */ Oid atttype = att_tup->atttypid; int32 atttypmod = att_tup->atttypmod; @@ -188,92 +191,96 @@ expand_targetlist(List *tlist, int command_type, switch (command_type) { case CMD_INSERT: - { + { #ifdef _DROP_COLUMN_HACK__ - Datum typedefault; + Datum typedefault; + #else - Datum typedefault = get_typdefault(atttype); -#endif /* _DROP_COLUMN_HACK__ */ - int typlen; - Const *temp_const; + Datum typedefault = get_typdefault(atttype); + +#endif /* _DROP_COLUMN_HACK__ */ + int typlen; + Const *temp_const; #ifdef _DROP_COLUMN_HACK__ - if (COLUMN_IS_DROPPED(att_tup)) - typedefault = PointerGetDatum(NULL); - else - typedefault = get_typdefault(atttype); -#endif /* _DROP_COLUMN_HACK__ */ - if (typedefault == PointerGetDatum(NULL)) - typlen = 0; - else - { - /* - * Since this is an append or replace, the size of - * any set attribute is the size of the OID used to - * represent it. - */ - if (att_tup->attisset) - typlen = get_typlen(OIDOID); + if (COLUMN_IS_DROPPED(att_tup)) + typedefault = PointerGetDatum(NULL); + else + typedefault = get_typdefault(atttype); +#endif /* _DROP_COLUMN_HACK__ */ + if (typedefault == PointerGetDatum(NULL)) + typlen = 0; else - typlen = get_typlen(atttype); + { + + /* + * Since this is an append or replace, the + * size of any set attribute is the size of + * the OID used to represent it. + */ + if (att_tup->attisset) + typlen = get_typlen(OIDOID); + else + typlen = get_typlen(atttype); + } + + temp_const = makeConst(atttype, + typlen, + typedefault, + (typedefault == PointerGetDatum(NULL)), + false, + false, /* not a set */ + false); + + new_tle = makeTargetEntry(makeResdom(attrno, + atttype, + -1, + pstrdup(attrname), + 0, + (Oid) 0, + false), + (Node *) temp_const); + break; } - - temp_const = makeConst(atttype, - typlen, - typedefault, - (typedefault == PointerGetDatum(NULL)), - false, - false, /* not a set */ - false); - - new_tle = makeTargetEntry(makeResdom(attrno, - atttype, - -1, - pstrdup(attrname), - 0, - (Oid) 0, - false), - (Node *) temp_const); - break; - } case CMD_UPDATE: - { - Var *temp_var; + { + Var *temp_var; #ifdef _DROP_COLUMN_HACK__ - Node *temp_node = (Node *) NULL; - if (COLUMN_IS_DROPPED(att_tup)) - { - temp_node = (Node *)makeConst(atttype, 0, - PointerGetDatum(NULL), - true, - false, - false, /* not a set */ - false); - } - else -#endif /* _DROP_COLUMN_HACK__ */ - temp_var = makeVar(result_relation, attrno, atttype, - atttypmod, 0); + Node *temp_node = (Node *) NULL; + + if (COLUMN_IS_DROPPED(att_tup)) + { + temp_node = (Node *) makeConst(atttype, 0, + PointerGetDatum(NULL), + true, + false, + false, /* not a set */ + false); + } + else +#endif /* _DROP_COLUMN_HACK__ */ + temp_var = makeVar(result_relation, attrno, atttype, + atttypmod, 0); #ifdef _DROP_COLUMN_HACK__ - if (!temp_node) - temp_node = (Node *) temp_var; -#endif /* _DROP_COLUMN_HACK__ */ - - new_tle = makeTargetEntry(makeResdom(attrno, - atttype, - atttypmod, - pstrdup(attrname), - 0, - (Oid) 0, - false), + if (!temp_node) + temp_node = (Node *) temp_var; +#endif /* _DROP_COLUMN_HACK__ */ + + new_tle = makeTargetEntry(makeResdom(attrno, + atttype, + atttypmod, + pstrdup(attrname), + 0, + (Oid) 0, + false), #ifdef _DROP_COLUMN_HACK__ - temp_node); + temp_node); #else - (Node *) temp_var); -#endif /* _DROP_COLUMN_HACK__ */ - break; - } + (Node *) temp_var); +#endif /* _DROP_COLUMN_HACK__ */ + break; + } default: elog(ERROR, "expand_targetlist: unexpected command_type"); break; @@ -285,18 +292,19 @@ expand_targetlist(List *tlist, int command_type, /* * Copy all unprocessed tlist entries to the end of the new tlist, - * making sure they are marked resjunk = true. Typical junk entries - * include ORDER BY or GROUP BY expressions (are these actually possible - * in an INSERT or UPDATE?), system attribute references, etc. + * making sure they are marked resjunk = true. Typical junk entries + * include ORDER BY or GROUP BY expressions (are these actually + * possible in an INSERT or UPDATE?), system attribute references, + * etc. */ old_tlist_index = 0; foreach(temp, tlist) { - TargetEntry *old_tle = (TargetEntry *) lfirst(temp); + TargetEntry *old_tle = (TargetEntry *) lfirst(temp); - if (! tlistentry_used[old_tlist_index]) + if (!tlistentry_used[old_tlist_index]) { - Resdom *resdom; + Resdom *resdom; resdom = (Resdom *) copyObject((Node *) old_tle->resdom); resdom->resno = attrno++; diff --git a/src/backend/optimizer/prep/prepunion.c b/src/backend/optimizer/prep/prepunion.c index e866a5032fc..cd2baf6bbb8 100644 --- a/src/backend/optimizer/prep/prepunion.c +++ b/src/backend/optimizer/prep/prepunion.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.47 2000/03/21 05:12:06 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.48 2000/04/12 17:15:23 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -26,7 +26,8 @@ #include "parser/parsetree.h" #include "utils/lsyscache.h" -typedef struct { +typedef struct +{ Index rt_index; int sublevels_up; Oid old_relid; @@ -40,11 +41,11 @@ static RangeTblEntry *new_rangetable_entry(Oid new_relid, RangeTblEntry *old_entry); static void fix_parsetree_attnums(Index rt_index, Oid old_relid, Oid new_relid, Query *parsetree); -static bool fix_parsetree_attnums_walker (Node *node, - fix_parsetree_attnums_context *context); +static bool fix_parsetree_attnums_walker(Node *node, + fix_parsetree_attnums_context *context); static Append *make_append(List *appendplans, List *unionrtables, - Index rt_index, - List *inheritrtable, List *tlist); + Index rt_index, + List *inheritrtable, List *tlist); /* @@ -122,11 +123,11 @@ plan_union_queries(Query *parse) /* Is this a simple one */ if (!union_all_found || !union_found || - /* A trailing UNION negates the effect of earlier UNION ALLs */ + /* A trailing UNION negates the effect of earlier UNION ALLs */ !last_union_all_flag) { List *hold_unionClause = parse->unionClause; - double tuple_fraction = -1.0; /* default processing */ + double tuple_fraction = -1.0; /* default processing */ /* we will do sorting later, so don't do it now */ if (!union_all_found || @@ -134,6 +135,7 @@ plan_union_queries(Query *parse) { parse->sortClause = NIL; parse->distinctClause = NIL; + /* * force lower-level planning to assume that all tuples will * be retrieved, even if it sees a LIMIT in the query node. @@ -149,8 +151,9 @@ plan_union_queries(Query *parse) { Query *union_query = lfirst(ulist); - /* use subquery_planner here because the union'd queries - * have not been preprocessed yet. My goodness this is messy... + /* + * use subquery_planner here because the union'd queries have + * not been preprocessed yet. My goodness this is messy... */ union_plans = lappend(union_plans, subquery_planner(union_query, @@ -178,8 +181,8 @@ plan_union_queries(Query *parse) * Recursion, but UNION only. The last one is a UNION, so it will * not come here in recursion. * - * XXX is it OK to pass default -1 to union_planner in this path, - * or should we force a tuple_fraction value? + * XXX is it OK to pass default -1 to union_planner in this path, or + * should we force a tuple_fraction value? */ union_plans = lcons(union_planner(parse, -1.0), NIL); union_rts = lcons(parse->rtable, NIL); @@ -189,11 +192,12 @@ plan_union_queries(Query *parse) { Query *union_all_query = lfirst(ulist); - /* use subquery_planner here because the union'd queries - * have not been preprocessed yet. My goodness this is messy... + /* + * use subquery_planner here because the union'd queries have + * not been preprocessed yet. My goodness this is messy... */ union_plans = lappend(union_plans, - subquery_planner(union_all_query, -1.0)); + subquery_planner(union_all_query, -1.0)); union_rts = lappend(union_rts, union_all_query->rtable); } } @@ -201,9 +205,11 @@ plan_union_queries(Query *parse) /* We have already split UNION and UNION ALL and we made it consistent */ if (!last_union_all_flag) { - /* Need SELECT DISTINCT behavior to implement UNION. - * Put back the held sortClause, add any missing columns to the - * sort clause, and set distinctClause properly. + + /* + * Need SELECT DISTINCT behavior to implement UNION. Put back the + * held sortClause, add any missing columns to the sort clause, + * and set distinctClause properly. */ List *slitem; @@ -215,7 +221,7 @@ plan_union_queries(Query *parse) SortClause *scl = (SortClause *) lfirst(slitem); TargetEntry *tle = get_sortgroupclause_tle(scl, parse->targetList); - if (! tle->resdom->resjunk) + if (!tle->resdom->resjunk) parse->distinctClause = lappend(parse->distinctClause, copyObject(scl)); } @@ -226,9 +232,10 @@ plan_union_queries(Query *parse) parse->distinctClause = NIL; } - /* Make sure we don't try to apply the first query's grouping stuff - * to the Append node, either. Basically we don't want union_planner - * to do anything when we return control, except add the top sort/unique + /* + * Make sure we don't try to apply the first query's grouping stuff to + * the Append node, either. Basically we don't want union_planner to + * do anything when we return control, except add the top sort/unique * nodes for DISTINCT processing if this wasn't UNION ALL, or the top * sort node if it was UNION ALL with a user-provided sort clause. */ @@ -259,13 +266,13 @@ plan_union_queries(Query *parse) * * If grouping, aggregation, or sorting is specified in the parent plan, * the subplans should not do any of those steps --- we must do those - * operations just once above the APPEND node. The given tlist has been + * operations just once above the APPEND node. The given tlist has been * modified appropriately to remove group/aggregate expressions, but the * Query node still has the relevant fields set. We remove them in the * copies used for subplans (see plan_inherit_query). * * NOTE: this can be invoked recursively if more than one inheritance wildcard - * is present. At each level of recursion, the first wildcard remaining in + * is present. At each level of recursion, the first wildcard remaining in * the rangetable is expanded. */ Append * @@ -282,8 +289,8 @@ plan_inherit_queries(Query *parse, List *tlist, Index rt_index) /* * Remove the flag for this relation, since we're about to handle it. - * XXX destructive change to parent parse tree, but necessary to prevent - * infinite recursion. + * XXX destructive change to parent parse tree, but necessary to + * prevent infinite recursion. */ rt_entry->inh = false; @@ -313,42 +320,44 @@ plan_inherit_query(Relids relids, List *union_plans = NIL; List *union_rtentries = NIL; List *save_tlist = root->targetList; - double tuple_fraction; + double tuple_fraction; List *i; /* * Avoid making copies of the root's tlist, which we aren't going to - * use anyway (we are going to make copies of the passed tlist, instead). + * use anyway (we are going to make copies of the passed tlist, + * instead). */ root->targetList = NIL; /* - * If we are going to need sorting or grouping at the top level, - * force lower-level planners to assume that all tuples will be - * retrieved. + * If we are going to need sorting or grouping at the top level, force + * lower-level planners to assume that all tuples will be retrieved. */ if (root->distinctClause || root->sortClause || root->groupClause || root->hasAggs) - tuple_fraction = 0.0; /* will need all tuples from each subplan */ + tuple_fraction = 0.0; /* will need all tuples from each subplan */ else - tuple_fraction = -1.0; /* default behavior is OK (I think) */ + tuple_fraction = -1.0; /* default behavior is OK (I think) */ foreach(i, relids) { int relid = lfirsti(i); + /* - * Make a modifiable copy of the original query, - * and replace the target rangetable entry with a new one - * identifying this child table. + * Make a modifiable copy of the original query, and replace the + * target rangetable entry with a new one identifying this child + * table. */ Query *new_root = copyObject(root); RangeTblEntry *new_rt_entry = new_rangetable_entry(relid, rt_entry); rt_store(rt_index, new_root->rtable, new_rt_entry); + /* - * Insert (a modifiable copy of) the desired simplified tlist - * into the subquery + * Insert (a modifiable copy of) the desired simplified tlist into + * the subquery */ new_root->targetList = copyObject(tlist); @@ -360,14 +369,15 @@ plan_inherit_query(Relids relids, new_root->sortClause = NIL; new_root->groupClause = NIL; new_root->havingQual = NULL; - new_root->hasAggs = false; /* shouldn't be any left ... */ + new_root->hasAggs = false; /* shouldn't be any left ... */ /* * Update attribute numbers in case child has different ordering * of columns than parent (as can happen after ALTER TABLE). * * XXX This is a crock, and it doesn't really work. It'd be better - * to fix ALTER TABLE to preserve consistency of attribute numbering. + * to fix ALTER TABLE to preserve consistency of attribute + * numbering. */ fix_parsetree_attnums(rt_index, rt_entry->relid, @@ -397,23 +407,24 @@ find_all_inheritors(Oid parentrel) List *unexamined_relids = lconsi(parentrel, NIL); /* - * While the queue of unexamined relids is nonempty, remove the - * first element, mark it examined, and find its direct descendants. - * NB: cannot use foreach(), since we modify the queue inside loop. + * While the queue of unexamined relids is nonempty, remove the first + * element, mark it examined, and find its direct descendants. NB: + * cannot use foreach(), since we modify the queue inside loop. */ while (unexamined_relids != NIL) { - Oid currentrel = lfirsti(unexamined_relids); - List *currentchildren; + Oid currentrel = lfirsti(unexamined_relids); + List *currentchildren; unexamined_relids = lnext(unexamined_relids); examined_relids = lappendi(examined_relids, currentrel); currentchildren = find_inheritance_children(currentrel); + /* - * Add to the queue only those children not already seen. - * This could probably be simplified to a plain nconc, - * because our inheritance relationships should always be a - * strict tree, no? Should never find any matches, ISTM... + * Add to the queue only those children not already seen. This + * could probably be simplified to a plain nconc, because our + * inheritance relationships should always be a strict tree, no? + * Should never find any matches, ISTM... */ currentchildren = set_differencei(currentchildren, examined_relids); unexamined_relids = LispUnioni(unexamined_relids, currentchildren); @@ -477,7 +488,7 @@ new_rangetable_entry(Oid new_relid, RangeTblEntry *old_entry) * 'old_relid' in 'parsetree' with the attribute numbers from * 'new_relid'. * - * The parsetree is MODIFIED IN PLACE. This is OK only because + * The parsetree is MODIFIED IN PLACE. This is OK only because * plan_inherit_query made a copy of the tree for us to hack upon. */ static void @@ -495,6 +506,7 @@ fix_parsetree_attnums(Index rt_index, context.old_relid = old_relid; context.new_relid = new_relid; context.sublevels_up = 0; + /* * We must scan both the targetlist and qual, but we know the * havingQual is empty, so we can ignore it. @@ -504,7 +516,7 @@ fix_parsetree_attnums(Index rt_index, } /* - * Adjust varnos for child tables. This routine makes it possible for + * Adjust varnos for child tables. This routine makes it possible for * child tables to have different column positions for the "same" attribute * as a parent, which helps ALTER TABLE ADD COLUMN. Unfortunately this isn't * nearly enough to make it work transparently; there are other places where @@ -513,8 +525,8 @@ fix_parsetree_attnums(Index rt_index, * ALTER TABLE... */ static bool -fix_parsetree_attnums_walker (Node *node, - fix_parsetree_attnums_context *context) +fix_parsetree_attnums_walker(Node *node, + fix_parsetree_attnums_context *context) { if (node == NULL) return false; @@ -534,9 +546,10 @@ fix_parsetree_attnums_walker (Node *node, } if (IsA(node, SubLink)) { + /* - * Standard expression_tree_walker will not recurse into subselect, - * but here we must do so. + * Standard expression_tree_walker will not recurse into + * subselect, but here we must do so. */ SubLink *sub = (SubLink *) node; @@ -588,9 +601,9 @@ make_append(List *appendplans, node->plan.plan_width = 0; foreach(subnode, appendplans) { - Plan *subplan = (Plan *) lfirst(subnode); + Plan *subplan = (Plan *) lfirst(subnode); - if (subnode == appendplans) /* first node? */ + if (subnode == appendplans) /* first node? */ node->plan.startup_cost = subplan->startup_cost; node->plan.total_cost += subplan->total_cost; node->plan.plan_rows += subplan->plan_rows; diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c index d429db93a03..7ddbe4190cc 100644 --- a/src/backend/optimizer/util/clauses.c +++ b/src/backend/optimizer/util/clauses.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.64 2000/04/04 01:21:46 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.65 2000/04/12 17:15:24 momjian Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -46,9 +46,9 @@ static bool pull_agg_clause_walker(Node *node, List **listptr); static bool contain_subplans_walker(Node *node, void *context); static bool pull_subplans_walker(Node *node, List **listptr); static bool check_subplans_for_ungrouped_vars_walker(Node *node, - Query *context); -static int is_single_func(Node *node); -static Node *eval_const_expressions_mutator (Node *node, void *context); + Query *context); +static int is_single_func(Node *node); +static Node *eval_const_expressions_mutator(Node *node, void *context); static Expr *simplify_op_or_func(Expr *expr, List *args); @@ -340,18 +340,19 @@ make_ands_explicit(List *andclauses) List * make_ands_implicit(Expr *clause) { + /* * NB: because the parser sets the qual field to NULL in a query that * has no WHERE clause, we must consider a NULL input clause as TRUE, - * even though one might more reasonably think it FALSE. Grumble. - * If this causes trouble, consider changing the parser's behavior. + * even though one might more reasonably think it FALSE. Grumble. If + * this causes trouble, consider changing the parser's behavior. */ if (clause == NULL) return NIL; /* NULL -> NIL list == TRUE */ else if (and_clause((Node *) clause)) return clause->args; else if (IsA(clause, Const) && - ! ((Const *) clause)->constisnull && + !((Const *) clause)->constisnull && DatumGetInt32(((Const *) clause)->constvalue)) return NIL; /* constant TRUE input -> NIL list */ else @@ -381,7 +382,8 @@ contain_agg_clause_walker(Node *node, void *context) if (node == NULL) return false; if (IsA(node, Aggref)) - return true; /* abort the tree traversal and return true */ + return true; /* abort the tree traversal and return + * true */ return expression_tree_walker(node, contain_agg_clause_walker, context); } @@ -411,12 +413,14 @@ pull_agg_clause_walker(Node *node, List **listptr) if (IsA(node, Aggref)) { *listptr = lappend(*listptr, node); + /* * Complain if the aggregate's argument contains any aggregates; * nested agg functions are semantically nonsensical. */ if (contain_agg_clause(((Aggref *) node)->target)) elog(ERROR, "Aggregate function calls may not be nested"); + /* * Having checked that, we need not recurse into the argument. */ @@ -454,7 +458,8 @@ contain_subplans_walker(Node *node, void *context) if (node == NULL) return false; if (is_subplan(node) || IsA(node, SubLink)) - return true; /* abort the tree traversal and return true */ + return true; /* abort the tree traversal and return + * true */ return expression_tree_walker(node, contain_subplans_walker, context); } @@ -462,7 +467,7 @@ contain_subplans_walker(Node *node, void *context) * pull_subplans * Recursively pulls all subplans from an expression tree. * - * Returns list of subplan nodes found. Note the nodes themselves are not + * Returns list of subplan nodes found. Note the nodes themselves are not * copied, only referenced. */ List * @@ -507,7 +512,11 @@ void check_subplans_for_ungrouped_vars(Node *clause, Query *query) { - /* No special setup needed; context for walker is just the Query pointer */ + + /* + * No special setup needed; context for walker is just the Query + * pointer + */ check_subplans_for_ungrouped_vars_walker(clause, query); } @@ -517,17 +526,19 @@ check_subplans_for_ungrouped_vars_walker(Node *node, { if (node == NULL) return false; + /* - * We can ignore Vars other than in subplan args lists, - * since the parser already checked 'em. + * We can ignore Vars other than in subplan args lists, since the + * parser already checked 'em. */ if (is_subplan(node)) { + /* * The args list of the subplan node represents attributes from * outside passed into the sublink. */ - List *t; + List *t; foreach(t, ((Expr *) node)->args) { @@ -539,10 +550,10 @@ check_subplans_for_ungrouped_vars_walker(Node *node, /* * We do not care about args that are not local variables; * params or outer-level vars are not our responsibility to - * check. (The outer-level query passing them to us needs - * to worry, instead.) + * check. (The outer-level query passing them to us needs to + * worry, instead.) */ - if (! IsA(thisarg, Var)) + if (!IsA(thisarg, Var)) continue; var = (Var *) thisarg; if (var->varlevelsup > 0) @@ -554,8 +565,8 @@ check_subplans_for_ungrouped_vars_walker(Node *node, contained_in_group_clause = false; foreach(gl, context->groupClause) { - GroupClause *gcl = lfirst(gl); - Node *groupexpr; + GroupClause *gcl = lfirst(gl); + Node *groupexpr; groupexpr = get_sortgroupclause_expr(gcl, context->targetList); @@ -569,14 +580,14 @@ check_subplans_for_ungrouped_vars_walker(Node *node, if (!contained_in_group_clause) { /* Found an ungrouped argument. Complain. */ - RangeTblEntry *rte; - char *attname; + RangeTblEntry *rte; + char *attname; Assert(var->varno > 0 && var->varno <= length(context->rtable)); rte = rt_fetch(var->varno, context->rtable); attname = get_attname(rte->relid, var->varattno); - if (! attname) + if (!attname) elog(ERROR, "cache lookup of attribute %d in relation %u failed", var->varattno, rte->relid); elog(ERROR, "Sub-SELECT uses un-GROUPed attribute %s.%s from outer query", @@ -585,7 +596,7 @@ check_subplans_for_ungrouped_vars_walker(Node *node, } } return expression_tree_walker(node, - check_subplans_for_ungrouped_vars_walker, + check_subplans_for_ungrouped_vars_walker, (void *) context); } @@ -697,7 +708,7 @@ NumRelids(Node *clause) * is referenced in the clause). The routine checks that the * expression is of the form (var op something) or (something op var) * where the var is an attribute of the specified relation, or - * a function of a var of the specified relation. If so, it + * a function of a var of the specified relation. If so, it * returns the following info: * the found relation number (same as targetrelid unless that is 0) * the found var number (or InvalidAttrNumber if a function) @@ -707,7 +718,7 @@ NumRelids(Node *clause) * specifically 0 for the relid and attno, 0 for the constant value. * * Note that negative attno values are *not* invalid, but represent - * system attributes such as OID. It's sufficient to check for relid=0 + * system attributes such as OID. It's sufficient to check for relid=0 * to determine whether the routine succeeded. */ void @@ -785,15 +796,13 @@ default_results: *flag |= SEL_CONSTANT; } else - { *constval = 0; - } } /* * is_single_func - * If the given expression is a function of a single relation, - * return the relation number; else return 0 + * If the given expression is a function of a single relation, + * return the relation number; else return 0 */ static int is_single_func(Node *node) @@ -804,7 +813,7 @@ is_single_func(Node *node) if (length(varnos) == 1) { - int funcvarno = lfirsti(varnos); + int funcvarno = lfirsti(varnos); freeList(varnos); return funcvarno; @@ -922,7 +931,7 @@ CommuteClause(Expr *clause) * expression tree, for example "2 + 2" => "4". More interestingly, * we can reduce certain boolean expressions even when they contain * non-constant subexpressions: "x OR true" => "true" no matter what - * the subexpression x is. (XXX We assume that no such subexpression + * the subexpression x is. (XXX We assume that no such subexpression * will have important side-effects, which is not necessarily a good * assumption in the presence of user-defined functions; do we need a * pg_proc flag that prevents discarding the execution of a function?) @@ -954,7 +963,7 @@ eval_const_expressions(Node *node) } static Node * -eval_const_expressions_mutator (Node *node, void *context) +eval_const_expressions_mutator(Node *node, void *context) { if (node == NULL) return NULL; @@ -963,21 +972,22 @@ eval_const_expressions_mutator (Node *node, void *context) Expr *expr = (Expr *) node; List *args; Const *const_input; - Expr *newexpr; + Expr *newexpr; /* * Reduce constants in the Expr's arguments. We know args is - * either NIL or a List node, so we can call expression_tree_mutator - * directly rather than recursing to self. + * either NIL or a List node, so we can call + * expression_tree_mutator directly rather than recursing to self. */ args = (List *) expression_tree_mutator((Node *) expr->args, - eval_const_expressions_mutator, + eval_const_expressions_mutator, (void *) context); switch (expr->opType) { case OP_EXPR: case FUNC_EXPR: + /* * Code for op/func case is pretty bulky, so split it out * as a separate function. @@ -985,123 +995,131 @@ eval_const_expressions_mutator (Node *node, void *context) newexpr = simplify_op_or_func(expr, args); if (newexpr) /* successfully simplified it */ return (Node *) newexpr; - /* else fall out to build new Expr node with simplified args */ - break; - case OR_EXPR: - { + /* - * OR arguments are handled as follows: - * non constant: keep - * FALSE: drop (does not affect result) - * TRUE: force result to TRUE - * NULL: keep only one - * We keep one NULL input because ExecEvalOr returns - * NULL when no input is TRUE and at least one is NULL. + * else fall out to build new Expr node with simplified + * args */ - List *newargs = NIL; - List *arg; - bool haveNull = false; - bool forceTrue = false; - - foreach(arg, args) + break; + case OR_EXPR: { - if (! IsA(lfirst(arg), Const)) + + /* + * OR arguments are handled as follows: non constant: + * keep FALSE: drop (does not affect result) TRUE: + * force result to TRUE NULL: keep only one We keep + * one NULL input because ExecEvalOr returns NULL when + * no input is TRUE and at least one is NULL. + */ + List *newargs = NIL; + List *arg; + bool haveNull = false; + bool forceTrue = false; + + foreach(arg, args) { - newargs = lappend(newargs, lfirst(arg)); - continue; + if (!IsA(lfirst(arg), Const)) + { + newargs = lappend(newargs, lfirst(arg)); + continue; + } + const_input = (Const *) lfirst(arg); + if (const_input->constisnull) + haveNull = true; + else if (DatumGetInt32(const_input->constvalue)) + forceTrue = true; + /* otherwise, we can drop the constant-false input */ } - const_input = (Const *) lfirst(arg); - if (const_input->constisnull) - haveNull = true; - else if (DatumGetInt32(const_input->constvalue)) - forceTrue = true; - /* otherwise, we can drop the constant-false input */ + + /* + * We could return TRUE before falling out of the + * loop, but this coding method will be easier to + * adapt if we ever add a notion of non-removable + * functions. We'd need to check all the inputs for + * non-removability. + */ + if (forceTrue) + return MAKEBOOLCONST(true, false); + if (haveNull) + newargs = lappend(newargs, MAKEBOOLCONST(false, true)); + /* If all the inputs are FALSE, result is FALSE */ + if (newargs == NIL) + return MAKEBOOLCONST(false, false); + /* If only one nonconst-or-NULL input, it's the result */ + if (lnext(newargs) == NIL) + return (Node *) lfirst(newargs); + /* Else we still need an OR node */ + return (Node *) make_orclause(newargs); } - /* - * We could return TRUE before falling out of the loop, - * but this coding method will be easier to adapt if - * we ever add a notion of non-removable functions. - * We'd need to check all the inputs for non-removability. - */ - if (forceTrue) - return MAKEBOOLCONST(true, false); - if (haveNull) - newargs = lappend(newargs, MAKEBOOLCONST(false, true)); - /* If all the inputs are FALSE, result is FALSE */ - if (newargs == NIL) - return MAKEBOOLCONST(false, false); - /* If only one nonconst-or-NULL input, it's the result */ - if (lnext(newargs) == NIL) - return (Node *) lfirst(newargs); - /* Else we still need an OR node */ - return (Node *) make_orclause(newargs); - } case AND_EXPR: - { - /* - * AND arguments are handled as follows: - * non constant: keep - * TRUE: drop (does not affect result) - * FALSE: force result to FALSE - * NULL: keep only one - * We keep one NULL input because ExecEvalAnd returns - * NULL when no input is FALSE and at least one is NULL. - */ - List *newargs = NIL; - List *arg; - bool haveNull = false; - bool forceFalse = false; - - foreach(arg, args) { - if (! IsA(lfirst(arg), Const)) + + /* + * AND arguments are handled as follows: non constant: + * keep TRUE: drop (does not affect result) FALSE: + * force result to FALSE NULL: keep only one We keep + * one NULL input because ExecEvalAnd returns NULL + * when no input is FALSE and at least one is NULL. + */ + List *newargs = NIL; + List *arg; + bool haveNull = false; + bool forceFalse = false; + + foreach(arg, args) { - newargs = lappend(newargs, lfirst(arg)); - continue; + if (!IsA(lfirst(arg), Const)) + { + newargs = lappend(newargs, lfirst(arg)); + continue; + } + const_input = (Const *) lfirst(arg); + if (const_input->constisnull) + haveNull = true; + else if (!DatumGetInt32(const_input->constvalue)) + forceFalse = true; + /* otherwise, we can drop the constant-true input */ } - const_input = (Const *) lfirst(arg); - if (const_input->constisnull) - haveNull = true; - else if (! DatumGetInt32(const_input->constvalue)) - forceFalse = true; - /* otherwise, we can drop the constant-true input */ + + /* + * We could return FALSE before falling out of the + * loop, but this coding method will be easier to + * adapt if we ever add a notion of non-removable + * functions. We'd need to check all the inputs for + * non-removability. + */ + if (forceFalse) + return MAKEBOOLCONST(false, false); + if (haveNull) + newargs = lappend(newargs, MAKEBOOLCONST(false, true)); + /* If all the inputs are TRUE, result is TRUE */ + if (newargs == NIL) + return MAKEBOOLCONST(true, false); + /* If only one nonconst-or-NULL input, it's the result */ + if (lnext(newargs) == NIL) + return (Node *) lfirst(newargs); + /* Else we still need an AND node */ + return (Node *) make_andclause(newargs); } - /* - * We could return FALSE before falling out of the loop, - * but this coding method will be easier to adapt if - * we ever add a notion of non-removable functions. - * We'd need to check all the inputs for non-removability. - */ - if (forceFalse) - return MAKEBOOLCONST(false, false); - if (haveNull) - newargs = lappend(newargs, MAKEBOOLCONST(false, true)); - /* If all the inputs are TRUE, result is TRUE */ - if (newargs == NIL) - return MAKEBOOLCONST(true, false); - /* If only one nonconst-or-NULL input, it's the result */ - if (lnext(newargs) == NIL) - return (Node *) lfirst(newargs); - /* Else we still need an AND node */ - return (Node *) make_andclause(newargs); - } case NOT_EXPR: Assert(length(args) == 1); - if (! IsA(lfirst(args), Const)) + if (!IsA(lfirst(args), Const)) break; const_input = (Const *) lfirst(args); /* NOT NULL => NULL */ if (const_input->constisnull) return MAKEBOOLCONST(false, true); /* otherwise pretty easy */ - return MAKEBOOLCONST(! DatumGetInt32(const_input->constvalue), + return MAKEBOOLCONST(!DatumGetInt32(const_input->constvalue), false); case SUBPLAN_EXPR: + /* * Safety measure per notes at head of this routine: - * return a SubPlan unchanged. Too late to do anything + * return a SubPlan unchanged. Too late to do anything * with it. The arglist simplification above was wasted - * work (the list probably only contains Var nodes anyway). + * work (the list probably only contains Var nodes + * anyway). */ return (Node *) expr; default: @@ -1112,25 +1130,26 @@ eval_const_expressions_mutator (Node *node, void *context) /* * If we break out of the above switch on opType, then the - * expression cannot be simplified any further, so build - * and return a replacement Expr node using the - * possibly-simplified arguments and the original oper node. - * Can't use make_clause() here because we want to be sure - * the typeOid field is preserved... + * expression cannot be simplified any further, so build and + * return a replacement Expr node using the possibly-simplified + * arguments and the original oper node. Can't use make_clause() + * here because we want to be sure the typeOid field is + * preserved... */ newexpr = makeNode(Expr); - newexpr->typeOid = expr->typeOid; - newexpr->opType = expr->opType; - newexpr->oper = expr->oper; - newexpr->args = args; - return (Node *) newexpr; + newexpr->typeOid = expr->typeOid; + newexpr->opType = expr->opType; + newexpr->oper = expr->oper; + newexpr->args = args; + return (Node *) newexpr; } if (IsA(node, RelabelType)) { + /* * If we can simplify the input to a constant, then we don't need - * the RelabelType node anymore: just change the type field of - * the Const node. Otherwise, copy the RelabelType node. + * the RelabelType node anymore: just change the type field of the + * Const node. Otherwise, copy the RelabelType node. */ RelabelType *relabel = (RelabelType *) node; Node *arg; @@ -1138,13 +1157,15 @@ eval_const_expressions_mutator (Node *node, void *context) arg = eval_const_expressions_mutator(relabel->arg, context); if (arg && IsA(arg, Const)) { - Const *con = (Const *) arg; + Const *con = (Const *) arg; con->consttype = relabel->resulttype; + /* * relabel's resulttypmod is discarded, which is OK for now; * if the type actually needs a runtime length coercion then - * there should be a function call to do it just above this node. + * there should be a function call to do it just above this + * node. */ return (Node *) con; } @@ -1160,15 +1181,15 @@ eval_const_expressions_mutator (Node *node, void *context) } if (IsA(node, CaseExpr)) { + /* - * CASE expressions can be simplified if there are constant condition - * clauses: - * FALSE (or NULL): drop the alternative - * TRUE: drop all remaining alternatives - * If the first non-FALSE alternative is a constant TRUE, we can - * simplify the entire CASE to that alternative's expression. - * If there are no non-FALSE alternatives, we simplify the entire - * CASE to the default result (ELSE result). + * CASE expressions can be simplified if there are constant + * condition clauses: FALSE (or NULL): drop the alternative TRUE: + * drop all remaining alternatives If the first non-FALSE + * alternative is a constant TRUE, we can simplify the entire CASE + * to that alternative's expression. If there are no non-FALSE + * alternatives, we simplify the entire CASE to the default result + * (ELSE result). */ CaseExpr *caseexpr = (CaseExpr *) node; CaseExpr *newcase; @@ -1181,26 +1202,29 @@ eval_const_expressions_mutator (Node *node, void *context) { /* Simplify this alternative's condition and result */ CaseWhen *casewhen = (CaseWhen *) - expression_tree_mutator((Node *) lfirst(arg), - eval_const_expressions_mutator, - (void *) context); + expression_tree_mutator((Node *) lfirst(arg), + eval_const_expressions_mutator, + (void *) context); + Assert(IsA(casewhen, CaseWhen)); if (casewhen->expr == NULL || - ! IsA(casewhen->expr, Const)) + !IsA(casewhen->expr, Const)) { newargs = lappend(newargs, casewhen); continue; } const_input = (Const *) casewhen->expr; if (const_input->constisnull || - ! DatumGetInt32(const_input->constvalue)) + !DatumGetInt32(const_input->constvalue)) continue; /* drop alternative with FALSE condition */ + /* - * Found a TRUE condition. If it's the first (un-dropped) + * Found a TRUE condition. If it's the first (un-dropped) * alternative, the CASE reduces to just this alternative. */ if (newargs == NIL) return casewhen->result; + /* * Otherwise, add it to the list, and drop all the rest. */ @@ -1211,7 +1235,11 @@ eval_const_expressions_mutator (Node *node, void *context) /* Simplify the default result */ defresult = eval_const_expressions_mutator(caseexpr->defresult, context); - /* If no non-FALSE alternatives, CASE reduces to the default result */ + + /* + * If no non-FALSE alternatives, CASE reduces to the default + * result + */ if (newargs == NIL) return defresult; /* Otherwise we need a new CASE node */ @@ -1224,21 +1252,21 @@ eval_const_expressions_mutator (Node *node, void *context) } if (IsA(node, Iter)) { + /* - * The argument of an Iter is normally a function call. - * We must not try to eliminate the function, but we - * can try to simplify its arguments. If, by chance, - * the arg is NOT a function then we go ahead and try to - * simplify it (by falling into expression_tree_mutator). - * Is that the right thing? + * The argument of an Iter is normally a function call. We must + * not try to eliminate the function, but we can try to simplify + * its arguments. If, by chance, the arg is NOT a function then + * we go ahead and try to simplify it (by falling into + * expression_tree_mutator). Is that the right thing? */ Iter *iter = (Iter *) node; if (is_funcclause(iter->iterexpr)) { - Expr *func = (Expr *) iter->iterexpr; - Expr *newfunc; - Iter *newiter; + Expr *func = (Expr *) iter->iterexpr; + Expr *newfunc; + Iter *newiter; newfunc = makeNode(Expr); newfunc->typeOid = func->typeOid; @@ -1254,12 +1282,13 @@ eval_const_expressions_mutator (Node *node, void *context) return (Node *) newiter; } } + /* * For any node type not handled above, we recurse using - * expression_tree_mutator, which will copy the node unchanged - * but try to simplify its arguments (if any) using this routine. - * For example: we cannot eliminate an ArrayRef node, but we - * might be able to simplify constant expressions in its subscripts. + * expression_tree_mutator, which will copy the node unchanged but try + * to simplify its arguments (if any) using this routine. For example: + * we cannot eliminate an ArrayRef node, but we might be able to + * simplify constant expressions in its subscripts. */ return expression_tree_mutator(node, eval_const_expressions_mutator, (void *) context); @@ -1289,31 +1318,32 @@ simplify_op_or_func(Expr *expr, List *args) HeapTuple func_tuple; Form_pg_proc funcform; Type resultType; - Expr *newexpr; + Expr *newexpr; Datum const_val; bool const_is_null; bool isDone; /* - * For an operator or function, we cannot simplify unless all the inputs - * are constants. (XXX possible future improvement: if the op/func is - * strict and at least one input is NULL, we could simplify to NULL. - * But we do not currently have any way to know if the op/func is strict - * or not. For now, a NULL input is treated the same as any other - * constant node.) + * For an operator or function, we cannot simplify unless all the + * inputs are constants. (XXX possible future improvement: if the + * op/func is strict and at least one input is NULL, we could simplify + * to NULL. But we do not currently have any way to know if the + * op/func is strict or not. For now, a NULL input is treated the + * same as any other constant node.) */ foreach(arg, args) { - if (! IsA(lfirst(arg), Const)) + if (!IsA(lfirst(arg), Const)) return NULL; } + /* - * Get the function procedure's OID and look to see - * whether it is marked proiscachable. + * Get the function procedure's OID and look to see whether it is + * marked proiscachable. */ if (expr->opType == OP_EXPR) { - Oper *oper = (Oper *) expr->oper; + Oper *oper = (Oper *) expr->oper; replace_opid(oper); /* OK to scribble on input to this extent */ funcid = oper->opid; @@ -1321,7 +1351,7 @@ simplify_op_or_func(Expr *expr, List *args) } else { - Func *func = (Func *) expr->oper; + Func *func = (Func *) expr->oper; funcid = func->funcid; result_typeid = func->functype; @@ -1333,21 +1363,23 @@ simplify_op_or_func(Expr *expr, List *args) if (!HeapTupleIsValid(func_tuple)) elog(ERROR, "Function OID %u does not exist", funcid); funcform = (Form_pg_proc) GETSTRUCT(func_tuple); - if (! funcform->proiscachable) + if (!funcform->proiscachable) return NULL; + /* * Also check to make sure it doesn't return a set. */ if (funcform->proretset) return NULL; + /* * OK, looks like we can simplify this operator/function. * * We use the executor's routine ExecEvalExpr() to avoid duplication of * code and ensure we get the same result as the executor would get. * - * Build a new Expr node containing the already-simplified arguments. - * The only other setup needed here is the replace_opid() that we already + * Build a new Expr node containing the already-simplified arguments. The + * only other setup needed here is the replace_opid() that we already * did for the OP_EXPR case. */ newexpr = makeNode(Expr); @@ -1355,21 +1387,23 @@ simplify_op_or_func(Expr *expr, List *args) newexpr->opType = expr->opType; newexpr->oper = expr->oper; newexpr->args = args; + /* * It is OK to pass econtext = NULL because none of the ExecEvalExpr() * code used in this situation will use econtext. That might seem - * fortuitous, but it's not so unreasonable --- a constant expression does - * not depend on context, by definition, n'est ce pas? + * fortuitous, but it's not so unreasonable --- a constant expression + * does not depend on context, by definition, n'est ce pas? */ const_val = ExecEvalExpr((Node *) newexpr, NULL, &const_is_null, &isDone); Assert(isDone); /* if this isn't set, we blew it... */ pfree(newexpr); + /* * Make the constant result node. * - * XXX would it be better to take the result type from the - * pg_proc tuple, rather than the Oper or Func node? + * XXX would it be better to take the result type from the pg_proc tuple, + * rather than the Oper or Func node? */ resultType = typeidType(result_typeid); return (Expr *) makeConst(result_typeid, typeLen(resultType), @@ -1426,8 +1460,8 @@ simplify_op_or_func(Expr *expr, List *args) * * The walker routine should return "false" to continue the tree walk, or * "true" to abort the walk and immediately return "true" to the top-level - * caller. This can be used to short-circuit the traversal if the walker - * has found what it came for. "false" is returned to the top-level caller + * caller. This can be used to short-circuit the traversal if the walker + * has found what it came for. "false" is returned to the top-level caller * iff no invocation of the walker returned "true". * * The node types handled by expression_tree_walker include all those @@ -1454,16 +1488,16 @@ simplify_op_or_func(Expr *expr, List *args) */ bool -expression_tree_walker(Node *node, bool (*walker) (), void *context) + expression_tree_walker(Node *node, bool (*walker) (), void *context) { List *temp; /* - * The walker has already visited the current node, - * and so we need only recurse into any sub-nodes it has. + * The walker has already visited the current node, and so we need + * only recurse into any sub-nodes it has. * - * We assume that the walker is not interested in List nodes per se, - * so when we expect a List we just recurse directly to self without + * We assume that the walker is not interested in List nodes per se, so + * when we expect a List we just recurse directly to self without * bothering to call the walker. */ if (node == NULL) @@ -1478,7 +1512,7 @@ expression_tree_walker(Node *node, bool (*walker) (), void *context) break; case T_Expr: { - Expr *expr = (Expr *) node; + Expr *expr = (Expr *) node; if (expr->opType == SUBPLAN_EXPR) { @@ -1500,6 +1534,7 @@ expression_tree_walker(Node *node, bool (*walker) (), void *context) case T_ArrayRef: { ArrayRef *aref = (ArrayRef *) node; + /* recurse directly for upper/lower array index lists */ if (expression_tree_walker((Node *) aref->refupperindexpr, walker, context)) @@ -1519,10 +1554,12 @@ expression_tree_walker(Node *node, bool (*walker) (), void *context) case T_CaseExpr: { CaseExpr *caseexpr = (CaseExpr *) node; + /* we assume walker doesn't care about CaseWhens, either */ foreach(temp, caseexpr->args) { CaseWhen *when = (CaseWhen *) lfirst(temp); + Assert(IsA(when, CaseWhen)); if (walker(when->expr, context)) return true; @@ -1538,12 +1575,14 @@ expression_tree_walker(Node *node, bool (*walker) (), void *context) break; case T_SubLink: { - SubLink *sublink = (SubLink *) node; + SubLink *sublink = (SubLink *) node; - /* If the SubLink has already been processed by subselect.c, - * it will have lefthand=NIL, and we only need to look at - * the oper list. Otherwise we only need to look at lefthand - * (the Oper nodes in the oper list are deemed uninteresting). + /* + * If the SubLink has already been processed by + * subselect.c, it will have lefthand=NIL, and we only + * need to look at the oper list. Otherwise we only need + * to look at lefthand (the Oper nodes in the oper list + * are deemed uninteresting). */ if (sublink->lefthand) return walker((Node *) sublink->lefthand, context); @@ -1628,18 +1667,19 @@ expression_tree_walker(Node *node, bool (*walker) (), void *context) */ Node * -expression_tree_mutator(Node *node, Node * (*mutator) (), void *context) + expression_tree_mutator(Node *node, Node *(*mutator) (), void *context) { + /* - * The mutator has already decided not to modify the current node, - * but we must call the mutator for any sub-nodes. + * The mutator has already decided not to modify the current node, but + * we must call the mutator for any sub-nodes. */ #define FLATCOPY(newnode, node, nodetype) \ ( (newnode) = makeNode(nodetype), \ memcpy((newnode), (node), sizeof(nodetype)) ) -#define CHECKFLATCOPY(newnode, node, nodetype) \ +#define CHECKFLATCOPY(newnode, node, nodetype) \ ( AssertMacro(IsA((node), nodetype)), \ (newnode) = makeNode(nodetype), \ memcpy((newnode), (node), sizeof(nodetype)) ) @@ -1659,31 +1699,41 @@ expression_tree_mutator(Node *node, Node * (*mutator) (), void *context) return (Node *) copyObject(node); case T_Expr: { - Expr *expr = (Expr *) node; - Expr *newnode; + Expr *expr = (Expr *) node; + Expr *newnode; FLATCOPY(newnode, expr, Expr); if (expr->opType == SUBPLAN_EXPR) { - SubLink *oldsublink = ((SubPlan *) expr->oper)->sublink; - SubPlan *newsubplan; + SubLink *oldsublink = ((SubPlan *) expr->oper)->sublink; + SubPlan *newsubplan; /* flat-copy the oper node, which is a SubPlan */ CHECKFLATCOPY(newsubplan, expr->oper, SubPlan); newnode->oper = (Node *) newsubplan; /* likewise its SubLink node */ CHECKFLATCOPY(newsubplan->sublink, oldsublink, SubLink); - /* transform args list (params to be passed to subplan) */ + + /* + * transform args list (params to be passed to + * subplan) + */ MUTATE(newnode->args, expr->args, List *); /* transform sublink's oper list as well */ - MUTATE(newsubplan->sublink->oper, oldsublink->oper, List*); - /* but not the subplan itself, which is referenced as-is */ + MUTATE(newsubplan->sublink->oper, oldsublink->oper, List *); + + /* + * but not the subplan itself, which is referenced + * as-is + */ } else { - /* for other Expr node types, just transform args list, - * linking to original oper node (OK?) + + /* + * for other Expr node types, just transform args + * list, linking to original oper node (OK?) */ MUTATE(newnode->args, expr->args, List *); } @@ -1692,8 +1742,8 @@ expression_tree_mutator(Node *node, Node * (*mutator) (), void *context) break; case T_Aggref: { - Aggref *aggref = (Aggref *) node; - Aggref *newnode; + Aggref *aggref = (Aggref *) node; + Aggref *newnode; FLATCOPY(newnode, aggref, Aggref); MUTATE(newnode->target, aggref->target, Node *); @@ -1702,8 +1752,8 @@ expression_tree_mutator(Node *node, Node * (*mutator) (), void *context) break; case T_Iter: { - Iter *iter = (Iter *) node; - Iter *newnode; + Iter *iter = (Iter *) node; + Iter *newnode; FLATCOPY(newnode, iter, Iter); MUTATE(newnode->iterexpr, iter->iterexpr, Node *); @@ -1763,12 +1813,14 @@ expression_tree_mutator(Node *node, Node * (*mutator) (), void *context) break; case T_SubLink: { - /* A "bare" SubLink (note we will not come here if we found - * a SUBPLAN_EXPR node above it). Transform the lefthand side, - * but not the oper list nor the subquery. + + /* + * A "bare" SubLink (note we will not come here if we + * found a SUBPLAN_EXPR node above it). Transform the + * lefthand side, but not the oper list nor the subquery. */ - SubLink *sublink = (SubLink *) node; - SubLink *newnode; + SubLink *sublink = (SubLink *) node; + SubLink *newnode; FLATCOPY(newnode, sublink, SubLink); MUTATE(newnode->lefthand, sublink->lefthand, List *); @@ -1777,9 +1829,12 @@ expression_tree_mutator(Node *node, Node * (*mutator) (), void *context) break; case T_List: { - /* We assume the mutator isn't interested in the list nodes - * per se, so just invoke it on each list element. - * NOTE: this would fail badly on a list with integer elements! + + /* + * We assume the mutator isn't interested in the list + * nodes per se, so just invoke it on each list element. + * NOTE: this would fail badly on a list with integer + * elements! */ List *resultlist = NIL; List *temp; @@ -1795,9 +1850,13 @@ expression_tree_mutator(Node *node, Node * (*mutator) (), void *context) break; case T_TargetEntry: { - /* We mutate the expression, but not the resdom, by default. */ - TargetEntry *targetentry = (TargetEntry *) node; - TargetEntry *newnode; + + /* + * We mutate the expression, but not the resdom, by + * default. + */ + TargetEntry *targetentry = (TargetEntry *) node; + TargetEntry *newnode; FLATCOPY(newnode, targetentry, TargetEntry); MUTATE(newnode->expr, targetentry->expr, Node *); diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c index 400c813125c..69a28138d8a 100644 --- a/src/backend/optimizer/util/pathnode.c +++ b/src/backend/optimizer/util/pathnode.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/util/pathnode.c,v 1.62 2000/03/22 22:08:35 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/util/pathnode.c,v 1.63 2000/04/12 17:15:24 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -42,6 +42,7 @@ compare_path_costs(Path *path1, Path *path2, CostSelector criterion) return -1; if (path1->startup_cost > path2->startup_cost) return +1; + /* * If paths have the same startup cost (not at all unlikely), * order them by total cost. @@ -57,6 +58,7 @@ compare_path_costs(Path *path1, Path *path2, CostSelector criterion) return -1; if (path1->total_cost > path2->total_cost) return +1; + /* * If paths have the same total cost, order them by startup cost. */ @@ -172,7 +174,8 @@ set_cheapest(RelOptInfo *parent_rel) void add_path(RelOptInfo *parent_rel, Path *new_path) { - bool accept_new = true; /* unless we find a superior old path */ + bool accept_new = true; /* unless we find a superior old + * path */ List *p1_prev = NIL; List *p1; @@ -184,36 +187,39 @@ add_path(RelOptInfo *parent_rel, Path *new_path) foreach(p1, parent_rel->pathlist) { Path *old_path = (Path *) lfirst(p1); - bool remove_old = false; /* unless new proves superior */ + bool remove_old = false; /* unless new proves superior */ int costcmp; costcmp = compare_path_costs(new_path, old_path, TOTAL_COST); + /* - * If the two paths compare differently for startup and total cost, - * then we want to keep both, and we can skip the (much slower) - * comparison of pathkeys. If they compare the same, proceed with - * the pathkeys comparison. Note this test relies on the fact that - * compare_path_costs will only return 0 if both costs are equal - * (and, therefore, there's no need to call it twice in that case). + * If the two paths compare differently for startup and total + * cost, then we want to keep both, and we can skip the (much + * slower) comparison of pathkeys. If they compare the same, + * proceed with the pathkeys comparison. Note this test relies on + * the fact that compare_path_costs will only return 0 if both + * costs are equal (and, therefore, there's no need to call it + * twice in that case). */ if (costcmp == 0 || - costcmp == compare_path_costs(new_path, old_path, STARTUP_COST)) + costcmp == compare_path_costs(new_path, old_path, STARTUP_COST)) { switch (compare_pathkeys(new_path->pathkeys, old_path->pathkeys)) { case PATHKEYS_EQUAL: if (costcmp < 0) - remove_old = true; /* new dominates old */ + remove_old = true; /* new dominates old */ else - accept_new = false; /* old equals or dominates new */ + accept_new = false; /* old equals or dominates + * new */ break; case PATHKEYS_BETTER1: if (costcmp <= 0) - remove_old = true; /* new dominates old */ + remove_old = true; /* new dominates old */ break; case PATHKEYS_BETTER2: if (costcmp >= 0) - accept_new = false; /* old dominates new */ + accept_new = false; /* old dominates new */ break; case PATHKEYS_DIFFERENT: /* keep both paths, since they have different ordering */ @@ -241,7 +247,7 @@ add_path(RelOptInfo *parent_rel, Path *new_path) * scanning the pathlist; we will not add new_path, and we assume * new_path cannot dominate any other elements of the pathlist. */ - if (! accept_new) + if (!accept_new) break; } @@ -315,12 +321,14 @@ create_index_path(Query *root, if (pathnode->path.pathkeys == NIL) { /* No ordering available from index, is that OK? */ - if (! ScanDirectionIsNoMovement(indexscandir)) + if (!ScanDirectionIsNoMovement(indexscandir)) elog(ERROR, "create_index_path: failed to create ordered index scan"); } else { - /* The index is ordered, and build_index_pathkeys defaulted to + + /* + * The index is ordered, and build_index_pathkeys defaulted to * forward scan, so make sure we mark the pathnode properly. */ if (ScanDirectionIsNoMovement(indexscandir)) @@ -341,11 +349,11 @@ create_index_path(Query *root, pathnode->indexscandir = indexscandir; /* - * This routine is only used to generate "standalone" indexpaths, - * not nestloop inner indexpaths. So joinrelids is always NIL - * and the number of rows is the same as the parent rel's estimate. + * This routine is only used to generate "standalone" indexpaths, not + * nestloop inner indexpaths. So joinrelids is always NIL and the + * number of rows is the same as the parent rel's estimate. */ - pathnode->joinrelids = NIL; /* no join clauses here */ + pathnode->joinrelids = NIL; /* no join clauses here */ pathnode->rows = rel->rows; cost_index(&pathnode->path, root, rel, index, indexquals, false); @@ -359,20 +367,23 @@ create_index_path(Query *root, * pathnode. * */ -TidPath * +TidPath * create_tidscan_path(RelOptInfo *rel, List *tideval) { - TidPath *pathnode = makeNode(TidPath); + TidPath *pathnode = makeNode(TidPath); pathnode->path.pathtype = T_TidScan; pathnode->path.parent = rel; pathnode->path.pathkeys = NIL; - pathnode->tideval = copyObject(tideval); /* is copy really necessary? */ + pathnode->tideval = copyObject(tideval); /* is copy really + * necessary? */ pathnode->unjoined_relids = NIL; cost_tidscan(&pathnode->path, rel, tideval); - /* divide selectivity for each clause to get an equal selectivity - * as IndexScan does OK ? + + /* + * divide selectivity for each clause to get an equal selectivity as + * IndexScan does OK ? */ return pathnode; @@ -485,7 +496,7 @@ create_mergejoin_path(RelOptInfo *joinrel, * 'innerdisbursion' is an estimate of the disbursion of the inner hash key * */ -HashPath * +HashPath * create_hashjoin_path(RelOptInfo *joinrel, Path *outer_path, Path *inner_path, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index 716c31ab0f1..e9d7690e00c 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.49 2000/02/18 09:30:09 inoue Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.50 2000/04/12 17:15:24 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -50,7 +50,7 @@ relation_info(Query *root, Index relid, Form_pg_class relation; relationTuple = SearchSysCacheTuple(RELOID, - ObjectIdGetDatum(relationObjectId), + ObjectIdGetDatum(relationObjectId), 0, 0, 0); if (!HeapTupleIsValid(relationTuple)) elog(ERROR, "relation_info: Relation %u not found", @@ -81,7 +81,7 @@ find_secondary_indexes(Query *root, Index relid) Oid indrelid = getrelid(relid, root->rtable); Relation relation; HeapScanDesc scan; - ScanKeyData indexKey; + ScanKeyData indexKey; HeapTuple indexTuple; /* Scan pg_index for tuples describing indexes of this rel */ @@ -97,27 +97,28 @@ find_secondary_indexes(Query *root, Index relid) while (HeapTupleIsValid(indexTuple = heap_getnext(scan, 0))) { - Form_pg_index index = (Form_pg_index) GETSTRUCT(indexTuple); - IndexOptInfo *info = makeNode(IndexOptInfo); - int i; - Relation indexRelation; - Oid relam; - uint16 amorderstrategy; + Form_pg_index index = (Form_pg_index) GETSTRUCT(indexTuple); + IndexOptInfo *info = makeNode(IndexOptInfo); + int i; + Relation indexRelation; + Oid relam; + uint16 amorderstrategy; /* * Need to make these arrays large enough to be sure there is a * terminating 0 at the end of each one. */ - info->classlist = (Oid *) palloc(sizeof(Oid) * (INDEX_MAX_KEYS+1)); - info->indexkeys = (int *) palloc(sizeof(int) * (INDEX_MAX_KEYS+1)); - info->ordering = (Oid *) palloc(sizeof(Oid) * (INDEX_MAX_KEYS+1)); + info->classlist = (Oid *) palloc(sizeof(Oid) * (INDEX_MAX_KEYS + 1)); + info->indexkeys = (int *) palloc(sizeof(int) * (INDEX_MAX_KEYS + 1)); + info->ordering = (Oid *) palloc(sizeof(Oid) * (INDEX_MAX_KEYS + 1)); /* Extract info from the pg_index tuple */ info->indexoid = index->indexrelid; - info->indproc = index->indproc; /* functional index ?? */ - if (VARSIZE(&index->indpred) != 0) /* partial index ?? */ + info->indproc = index->indproc; /* functional index ?? */ + if (VARSIZE(&index->indpred) != 0) /* partial index ?? */ { char *predString = fmgr(F_TEXTOUT, &index->indpred); + info->indpred = (List *) stringToNode(predString); pfree(predString); } @@ -143,26 +144,25 @@ find_secondary_indexes(Query *root, Index relid) index_close(indexRelation); /* - * Fetch the ordering operators associated with the index, - * if any. + * Fetch the ordering operators associated with the index, if any. */ - MemSet(info->ordering, 0, sizeof(Oid) * (INDEX_MAX_KEYS+1)); + MemSet(info->ordering, 0, sizeof(Oid) * (INDEX_MAX_KEYS + 1)); if (amorderstrategy != 0) { for (i = 0; i < INDEX_MAX_KEYS && index->indclass[i]; i++) { - HeapTuple amopTuple; - Form_pg_amop amop; + HeapTuple amopTuple; + Form_pg_amop amop; amopTuple = SearchSysCacheTuple(AMOPSTRATEGY, ObjectIdGetDatum(relam), - ObjectIdGetDatum(index->indclass[i]), + ObjectIdGetDatum(index->indclass[i]), UInt16GetDatum(amorderstrategy), 0); if (!HeapTupleIsValid(amopTuple)) elog(ERROR, "find_secondary_indexes: no amop %u %u %d", - relam, index->indclass[i], (int) amorderstrategy); + relam, index->indclass[i], (int) amorderstrategy); amop = (Form_pg_amop) GETSTRUCT(amopTuple); info->ordering[i] = amop->amopopr; } diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c index 694a1b905e1..da7059ce915 100644 --- a/src/backend/optimizer/util/relnode.c +++ b/src/backend/optimizer/util/relnode.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/util/relnode.c,v 1.25 2000/02/18 23:47:31 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/util/relnode.c,v 1.26 2000/04/12 17:15:24 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -24,15 +24,15 @@ static List *new_join_tlist(List *tlist, int first_resdomno); static List *build_joinrel_restrictlist(RelOptInfo *joinrel, - RelOptInfo *outer_rel, - RelOptInfo *inner_rel); + RelOptInfo *outer_rel, + RelOptInfo *inner_rel); static void build_joinrel_joinlist(RelOptInfo *joinrel, - RelOptInfo *outer_rel, - RelOptInfo *inner_rel); + RelOptInfo *outer_rel, + RelOptInfo *inner_rel); static List *subbuild_joinrel_restrictlist(RelOptInfo *joinrel, - List *joininfo_list); + List *joininfo_list); static void subbuild_joinrel_joinlist(RelOptInfo *joinrel, - List *joininfo_list); + List *joininfo_list); /* @@ -50,7 +50,10 @@ get_base_rel(Query *root, int relid) { rel = (RelOptInfo *) lfirst(baserels); - /* We know length(rel->relids) == 1 for all members of base_rel_list */ + /* + * We know length(rel->relids) == 1 for all members of + * base_rel_list + */ if (lfirsti(rel->relids) == relid) return rel; } @@ -75,18 +78,20 @@ get_base_rel(Query *root, int relid) if (relid < 0) { + /* - * If the relation is a materialized relation, assume - * constants for sizes. + * If the relation is a materialized relation, assume constants + * for sizes. */ rel->pages = _NONAME_RELATION_PAGES_; rel->tuples = _NONAME_RELATION_TUPLES_; } else { + /* - * Otherwise, retrieve relation statistics from the - * system catalogs. + * Otherwise, retrieve relation statistics from the system + * catalogs. */ relation_info(root, relid, &rel->indexed, &rel->pages, &rel->tuples); @@ -162,6 +167,7 @@ get_join_rel(Query *root, if (joinrel) { + /* * Yes, so we only need to figure the restrictlist for this * particular pair of component relations. @@ -198,13 +204,13 @@ get_join_rel(Query *root, * of the outer and inner join relations and then merging the results * together. * - * NOTE: the tlist order for a join rel will depend on which pair - * of outer and inner rels we first try to build it from. But the + * NOTE: the tlist order for a join rel will depend on which pair of + * outer and inner rels we first try to build it from. But the * contents should be the same regardless. * - * XXX someday: consider pruning vars from the join's targetlist - * if they are needed only to evaluate restriction clauses of this - * join, and will never be accessed at higher levels of the plantree. + * XXX someday: consider pruning vars from the join's targetlist if they + * are needed only to evaluate restriction clauses of this join, and + * will never be accessed at higher levels of the plantree. */ new_outer_tlist = new_join_tlist(outer_rel->targetlist, 1); new_inner_tlist = new_join_tlist(inner_rel->targetlist, @@ -212,9 +218,9 @@ get_join_rel(Query *root, joinrel->targetlist = nconc(new_outer_tlist, new_inner_tlist); /* - * Construct restrict and join clause lists for the new joinrel. - * (The caller might or might not need the restrictlist, but - * I need it anyway for set_joinrel_size_estimates().) + * Construct restrict and join clause lists for the new joinrel. (The + * caller might or might not need the restrictlist, but I need it + * anyway for set_joinrel_size_estimates().) */ restrictlist = build_joinrel_restrictlist(joinrel, outer_rel, inner_rel); if (restrictlist_ptr) @@ -246,7 +252,7 @@ get_join_rel(Query *root, * * XXX the above comment refers to code that is long dead and gone; * we don't keep track of joinlists for individual targetlist entries - * anymore. For now, all vars present in either input tlist will be + * anymore. For now, all vars present in either input tlist will be * emitted in the join's tlist. * * 'tlist' is the target list of one of the join relations @@ -286,16 +292,16 @@ new_join_tlist(List *tlist, * the join lists need only be computed once for any join RelOptInfo. * The join lists are fully determined by the set of rels making up the * joinrel, so we should get the same results (up to ordering) from any - * candidate pair of sub-relations. But the restriction list is whatever + * candidate pair of sub-relations. But the restriction list is whatever * is not handled in the sub-relations, so it depends on which * sub-relations are considered. * * If a join clause from an input relation refers to base rels still not * present in the joinrel, then it is still a join clause for the joinrel; - * we put it into an appropriate JoinInfo list for the joinrel. Otherwise, + * we put it into an appropriate JoinInfo list for the joinrel. Otherwise, * the clause is now a restrict clause for the joined relation, and we * return it to the caller of build_joinrel_restrictlist() to be stored in - * join paths made from this pair of sub-relations. (It will not need to + * join paths made from this pair of sub-relations. (It will not need to * be considered further up the join tree.) * * 'joinrel' is a join relation node @@ -304,11 +310,11 @@ new_join_tlist(List *tlist, * * build_joinrel_restrictlist() returns a list of relevant restrictinfos, * whereas build_joinrel_joinlist() stores its results in the joinrel's - * joininfo lists. One or the other must accept each given clause! + * joininfo lists. One or the other must accept each given clause! * * NB: Formerly, we made deep(!) copies of each input RestrictInfo to pass * up to the join relation. I believe this is no longer necessary, because - * RestrictInfo nodes are no longer context-dependent. Instead, just include + * RestrictInfo nodes are no longer context-dependent. Instead, just include * the original nodes in the lists made for the join relation. */ static List * @@ -316,9 +322,10 @@ build_joinrel_restrictlist(RelOptInfo *joinrel, RelOptInfo *outer_rel, RelOptInfo *inner_rel) { + /* - * We must eliminate duplicates, since we will see the - * same clauses arriving from both input relations... + * We must eliminate duplicates, since we will see the same clauses + * arriving from both input relations... */ return LispUnion(subbuild_joinrel_restrictlist(joinrel, outer_rel->joininfo), @@ -348,6 +355,7 @@ subbuild_joinrel_restrictlist(RelOptInfo *joinrel, if (is_subseti(joininfo->unjoined_relids, joinrel->relids)) { + /* * Clauses in this JoinInfo list become restriction clauses * for the joinrel, since they refer to no outside rels. @@ -360,9 +368,10 @@ subbuild_joinrel_restrictlist(RelOptInfo *joinrel, } else { + /* - * These clauses are still join clauses at this level, - * so we ignore them in this routine. + * These clauses are still join clauses at this level, so we + * ignore them in this routine. */ } } @@ -385,18 +394,20 @@ subbuild_joinrel_joinlist(RelOptInfo *joinrel, joinrel->relids); if (new_unjoined_relids == NIL) { + /* * Clauses in this JoinInfo list become restriction clauses - * for the joinrel, since they refer to no outside rels. - * So we can ignore them in this routine. + * for the joinrel, since they refer to no outside rels. So we + * can ignore them in this routine. */ } else { + /* - * These clauses are still join clauses at this level, - * so find or make the appropriate JoinInfo item for the joinrel, - * and add the clauses to it (eliminating duplicates). + * These clauses are still join clauses at this level, so find + * or make the appropriate JoinInfo item for the joinrel, and + * add the clauses to it (eliminating duplicates). */ JoinInfo *new_joininfo; diff --git a/src/backend/optimizer/util/tlist.c b/src/backend/optimizer/util/tlist.c index b4c745b25f3..d4094dac12a 100644 --- a/src/backend/optimizer/util/tlist.c +++ b/src/backend/optimizer/util/tlist.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/util/tlist.c,v 1.43 2000/01/27 18:11:34 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/util/tlist.c,v 1.44 2000/04/12 17:15:24 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -27,7 +27,7 @@ /* * tlistentry_member * Finds the (first) member of the given tlist whose expression is - * equal() to the given expression. Result is NULL if no such member. + * equal() to the given expression. Result is NULL if no such member. */ TargetEntry * tlistentry_member(Node *node, List *targetlist) @@ -36,7 +36,7 @@ tlistentry_member(Node *node, List *targetlist) foreach(temp, targetlist) { - TargetEntry *tlentry = (TargetEntry *) lfirst(temp); + TargetEntry *tlentry = (TargetEntry *) lfirst(temp); if (equal(node, tlentry->expr)) return tlentry; @@ -87,12 +87,12 @@ tlist_member(Node *node, List *targetlist) void add_var_to_tlist(RelOptInfo *rel, Var *var) { - if (! tlistentry_member((Node *) var, rel->targetlist)) + if (!tlistentry_member((Node *) var, rel->targetlist)) { /* XXX is copyObject necessary here? */ rel->targetlist = lappend(rel->targetlist, - create_tl_element((Var *) copyObject(var), - length(rel->targetlist) + 1)); + create_tl_element((Var *) copyObject(var), + length(rel->targetlist) + 1)); } } @@ -189,7 +189,7 @@ add_to_flat_tlist(List *tlist, List *vars) { Var *var = lfirst(v); - if (! tlistentry_member((Node *) var, tlist)) + if (!tlistentry_member((Node *) var, tlist)) { Resdom *r; diff --git a/src/backend/optimizer/util/var.c b/src/backend/optimizer/util/var.c index f438845cff9..bed7be7f08a 100644 --- a/src/backend/optimizer/util/var.c +++ b/src/backend/optimizer/util/var.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/util/var.c,v 1.25 2000/01/26 05:56:40 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/util/var.c,v 1.26 2000/04/12 17:15:24 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -20,7 +20,8 @@ #include "optimizer/var.h" -typedef struct { +typedef struct +{ List *varlist; bool includeUpperVars; } pull_var_clause_context; @@ -28,7 +29,7 @@ typedef struct { static bool pull_varnos_walker(Node *node, List **listptr); static bool contain_var_clause_walker(Node *node, void *context); static bool pull_var_clause_walker(Node *node, - pull_var_clause_context *context); + pull_var_clause_context *context); /* @@ -54,7 +55,8 @@ pull_varnos_walker(Node *node, List **listptr) return false; if (IsA(node, Var)) { - Var *var = (Var *) node; + Var *var = (Var *) node; + if (var->varlevelsup == 0 && !intMember(var->varno, *listptr)) *listptr = lconsi(var->varno, *listptr); return false; @@ -83,7 +85,8 @@ contain_var_clause_walker(Node *node, void *context) if (IsA(node, Var)) { if (((Var *) node)->varlevelsup == 0) - return true; /* abort the tree traversal and return true */ + return true; /* abort the tree traversal and return + * true */ return false; } return expression_tree_walker(node, contain_var_clause_walker, context); @@ -94,7 +97,7 @@ contain_var_clause_walker(Node *node, void *context) * Recursively pulls all var nodes from an expression clause. * * Upper-level vars (with varlevelsup > 0) are included only - * if includeUpperVars is true. Most callers probably want + * if includeUpperVars is true. Most callers probably want * to ignore upper-level vars. * * Returns list of varnodes found. Note the varnodes themselves are not @@ -103,7 +106,7 @@ contain_var_clause_walker(Node *node, void *context) List * pull_var_clause(Node *clause, bool includeUpperVars) { - pull_var_clause_context context; + pull_var_clause_context context; context.varlist = NIL; context.includeUpperVars = includeUpperVars; diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index a874c24f5e1..7658443a378 100644 --- a/src/backend/parser/analyze.c +++ b/src/backend/parser/analyze.c @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: analyze.c,v 1.141 2000/03/24 23:34:19 tgl Exp $ + * $Id: analyze.c,v 1.142 2000/04/12 17:15:26 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -28,7 +28,7 @@ #include "utils/builtins.h" #include "utils/numeric.h" -void CheckSelectForUpdate(Query *qry); /* no points for style... */ +void CheckSelectForUpdate(Query *qry); /* no points for style... */ static Query *transformStmt(ParseState *pstate, Node *stmt); static Query *transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt); @@ -48,8 +48,8 @@ static void transformConstraintAttrs(List *constraintList); static void transformColumnType(ParseState *pstate, ColumnDef *column); /* kluge to return extra info from transformCreateStmt() */ -static List *extras_before; -static List *extras_after; +static List *extras_before; +static List *extras_after; /* @@ -81,7 +81,7 @@ parse_analyze(List *pl, ParseState *parentParseState) while (extras_before != NIL) { result = lappend(result, - transformStmt(pstate, lfirst(extras_before))); + transformStmt(pstate, lfirst(extras_before))); if (pstate->p_target_relation != NULL) heap_close(pstate->p_target_relation, AccessShareLock); pstate->p_target_relation = NULL; @@ -147,13 +147,15 @@ transformStmt(ParseState *pstate, Node *parseTree) n->query = (Query *) transformStmt(pstate, (Node *) n->query); - /* If a list of column names was given, run through and insert these - * into the actual query tree. - thomas 2000-03-08 + /* + * If a list of column names was given, run through and + * insert these into the actual query tree. - thomas + * 2000-03-08 */ if (n->aliases != NIL) { - int i; - List *targetList = n->query->targetList; + int i; + List *targetList = n->query->targetList; if (length(targetList) < length(n->aliases)) elog(ERROR, "CREATE VIEW specifies %d columns" @@ -162,9 +164,10 @@ transformStmt(ParseState *pstate, Node *parseTree) for (i = 0; i < length(n->aliases); i++) { - Ident *id; + Ident *id; TargetEntry *te; - Resdom *rd; + Resdom *rd; + id = nth(i, n->aliases); Assert(nodeTag(id) == T_Ident); te = nth(i, targetList); @@ -210,9 +213,7 @@ transformStmt(ParseState *pstate, Node *parseTree) break; case T_AlterTableStmt: - { - result = transformAlterTableStmt(pstate, (AlterTableStmt *) parseTree); - } + result = transformAlterTableStmt(pstate, (AlterTableStmt *) parseTree); break; /*------------------------ @@ -311,7 +312,7 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt) * It is important that we finish processing all the SELECT subclauses * before we start doing any INSERT-specific processing; otherwise * the behavior of SELECT within INSERT might be different from a - * stand-alone SELECT. (Indeed, Postgres up through 6.5 had bugs of + * stand-alone SELECT. (Indeed, Postgres up through 6.5 had bugs of * just that nature...) *---------- */ @@ -323,7 +324,8 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt) qry->qual = transformWhereClause(pstate, stmt->whereClause); - /* Initial processing of HAVING clause is just like WHERE clause. + /* + * Initial processing of HAVING clause is just like WHERE clause. * Additional work will be done in optimizer/plan/planner.c. */ qry->havingQual = transformWhereClause(pstate, stmt->havingClause); @@ -338,7 +340,7 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt) qry->distinctClause = transformDistinctClause(pstate, stmt->distinctClause, qry->targetList, - & qry->sortClause); + &qry->sortClause); qry->hasSubLinks = pstate->p_hasSubLinks; qry->hasAggs = pstate->p_hasAggs; @@ -390,9 +392,11 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt) if (resnode->resjunk) { - /* Resjunk nodes need no additional processing, but be sure they - * have names and resnos that do not match any target columns; - * else rewriter or planner might get confused. + + /* + * Resjunk nodes need no additional processing, but be sure + * they have names and resnos that do not match any target + * columns; else rewriter or planner might get confused. */ resnode->resname = "?resjunk?"; resnode->resno = (AttrNumber) pstate->p_last_resno++; @@ -411,9 +415,9 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt) /* * It is possible that the targetlist has fewer entries than were in * the columns list. We do not consider this an error (perhaps we - * should, if the columns list was explictly given?). We must truncate - * the attrnos list to only include the attrs actually provided, - * else we will fail to apply defaults for them below. + * should, if the columns list was explictly given?). We must + * truncate the attrnos list to only include the attrs actually + * provided, else we will fail to apply defaults for them below. */ if (icolumns != NIL) attrnos = ltruncate(numuseratts, attrnos); @@ -422,8 +426,8 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt) * Add targetlist items to assign DEFAULT values to any columns that * have defaults and were not assigned to by the user. * - * XXX wouldn't it make more sense to do this further downstream, - * after the rule rewriter? + * XXX wouldn't it make more sense to do this further downstream, after + * the rule rewriter? */ rd_att = pstate->p_target_relation->rd_att; if (rd_att->constr && rd_att->constr->num_defval > 0) @@ -434,24 +438,26 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt) while (--ndef >= 0) { - AttrNumber attrno = defval[ndef].adnum; + AttrNumber attrno = defval[ndef].adnum; Form_pg_attribute thisatt = att[attrno - 1]; - TargetEntry *te; + TargetEntry *te; if (intMember((int) attrno, attrnos)) continue; /* there was a user-specified value */ + /* - * No user-supplied value, so add a targetentry with DEFAULT expr - * and correct data for the target column. + * No user-supplied value, so add a targetentry with DEFAULT + * expr and correct data for the target column. */ te = makeTargetEntry( - makeResdom(attrno, - thisatt->atttypid, - thisatt->atttypmod, - pstrdup(NameStr(thisatt->attname)), - 0, 0, false), - stringToNode(defval[ndef].adbin)); + makeResdom(attrno, + thisatt->atttypid, + thisatt->atttypmod, + pstrdup(NameStr(thisatt->attname)), + 0, 0, false), + stringToNode(defval[ndef].adbin)); qry->targetList = lappend(qry->targetList, te); + /* * Make sure the value is coerced to the target column type * (might not be right type if it's not a constant!) @@ -476,7 +482,7 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt) * Create a name for an implicitly created index, sequence, constraint, etc. * * The parameters are: the original table name, the original field name, and - * a "type" string (such as "seq" or "pkey"). The field name and/or type + * a "type" string (such as "seq" or "pkey"). The field name and/or type * can be NULL if not relevant. * * The result is a palloc'd string. @@ -484,12 +490,12 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt) * The basic result we want is "name1_name2_type", omitting "_name2" or * "_type" when those parameters are NULL. However, we must generate * a name with less than NAMEDATALEN characters! So, we truncate one or - * both names if necessary to make a short-enough string. The type part + * both names if necessary to make a short-enough string. The type part * is never truncated (so it had better be reasonably short). * * To reduce the probability of collisions, we might someday add more * smarts to this routine, like including some "hash" characters computed - * from the truncated characters. Currently it seems best to keep it simple, + * from the truncated characters. Currently it seems best to keep it simple, * so that the generated names are easily predictable by a person. */ static char * @@ -513,10 +519,11 @@ makeObjectName(char *name1, char *name2, char *typename) if (typename) overhead += strlen(typename) + 1; - availchars = NAMEDATALEN-1 - overhead; + availchars = NAMEDATALEN - 1 - overhead; - /* If we must truncate, preferentially truncate the longer name. - * This logic could be expressed without a loop, but it's simple and + /* + * If we must truncate, preferentially truncate the longer name. This + * logic could be expressed without a loop, but it's simple and * obvious as a loop. */ while (name1chars + name2chars > availchars) @@ -534,13 +541,13 @@ makeObjectName(char *name1, char *name2, char *typename) if (name2) { name[ndx++] = '_'; - strncpy(name+ndx, name2, name2chars); + strncpy(name + ndx, name2, name2chars); ndx += name2chars; } if (typename) { name[ndx++] = '_'; - strcpy(name+ndx, typename); + strcpy(name + ndx, typename); } else name[ndx] = '\0'; @@ -556,7 +563,8 @@ CreateIndexName(char *table_name, char *column_name, char *label, List *indices) List *ilist; char typename[NAMEDATALEN]; - /* The type name for makeObjectName is label, or labelN if that's + /* + * The type name for makeObjectName is label, or labelN if that's * necessary to prevent collisions among multiple indexes for the same * table. Note there is no check for collisions with already-existing * indexes; this ought to be rethought someday. @@ -570,6 +578,7 @@ CreateIndexName(char *table_name, char *column_name, char *label, List *indices) foreach(ilist, indices) { IndexStmt *index = lfirst(ilist); + if (strcmp(iname, index->idxname) == 0) break; } @@ -597,28 +606,28 @@ CreateIndexName(char *table_name, char *column_name, char *label, List *indices) static Query * transformCreateStmt(ParseState *pstate, CreateStmt *stmt) { - Query *q; - List *elements; - Node *element; - List *columns; - List *dlist; - ColumnDef *column; - List *constraints, - *clist; - Constraint *constraint; - List *fkconstraints, /* List of FOREIGN KEY constraints to */ - *fkclist; /* add finally */ - FkConstraint *fkconstraint; - List *keys; - Ident *key; - List *blist = NIL; /* "before list" of things to do before - * creating the table */ - List *ilist = NIL; /* "index list" of things to do after - * creating the table */ - IndexStmt *index, - *pkey = NULL; - IndexElem *iparam; - bool saw_nullable; + Query *q; + List *elements; + Node *element; + List *columns; + List *dlist; + ColumnDef *column; + List *constraints, + *clist; + Constraint *constraint; + List *fkconstraints, /* List of FOREIGN KEY constraints to */ + *fkclist; /* add finally */ + FkConstraint *fkconstraint; + List *keys; + Ident *key; + List *blist = NIL; /* "before list" of things to do before + * creating the table */ + List *ilist = NIL; /* "index list" of things to do after + * creating the table */ + IndexStmt *index, + *pkey = NULL; + IndexElem *iparam; + bool saw_nullable; q = makeNode(Query); q->commandType = CMD_UTILITY; @@ -647,18 +656,19 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt) { char *sname; char *qstring; - A_Const *snamenode; + A_Const *snamenode; FuncCall *funccallnode; CreateSeqStmt *sequence; /* - * Create appropriate constraints for SERIAL. We do this - * in full, rather than shortcutting, so that we will - * detect any conflicting constraints the user wrote - * (like a different DEFAULT). + * Create appropriate constraints for SERIAL. We do + * this in full, rather than shortcutting, so that we + * will detect any conflicting constraints the user + * wrote (like a different DEFAULT). */ sname = makeObjectName(stmt->relname, column->colname, "seq"); + /* * Create an expression tree representing the function * call nextval('"sequencename"') @@ -701,7 +711,7 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt) sequence->options = NIL; elog(NOTICE, "CREATE TABLE will create implicit sequence '%s' for SERIAL column '%s.%s'", - sequence->seqname, stmt->relname, column->colname); + sequence->seqname, stmt->relname, column->colname); blist = lcons(sequence, NIL); } @@ -724,12 +734,13 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt) */ if (IsA(constraint, FkConstraint)) { - Ident *id = makeNode(Ident); - id->name = column->colname; - id->indirection = NIL; - id->isRel = false; + Ident *id = makeNode(Ident); + + id->name = column->colname; + id->indirection = NIL; + id->isRel = false; - fkconstraint = (FkConstraint *)constraint; + fkconstraint = (FkConstraint *) constraint; fkconstraint->fk_attrs = lappend(NIL, id); fkconstraints = lappend(fkconstraints, constraint); @@ -747,7 +758,7 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt) break; case CONSTR_NOTNULL: - if (saw_nullable && ! column->is_not_null) + if (saw_nullable && !column->is_not_null) elog(ERROR, "CREATE TABLE/(NOT) NULL conflicting declaration" " for '%s.%s'", stmt->relname, column->colname); column->is_not_null = TRUE; @@ -910,7 +921,7 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt) if (strcmp(column->colname, key->name) == 0) break; } - if (columns == NIL) /* fell off end of list? */ + if (columns == NIL) /* fell off end of list? */ elog(ERROR, "CREATE TABLE: column '%s' named in key does not exist", key->name); @@ -927,7 +938,7 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt) index->idxname = CreateIndexName(stmt->relname, iparam->name, "key", ilist); } - if (index->idxname == NULL) /* should not happen */ + if (index->idxname == NULL) /* should not happen */ elog(ERROR, "CREATE TABLE: failed to make implicit index name"); ilist = lappend(ilist, index); @@ -945,9 +956,11 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt) ilist = NIL; while (dlist != NIL) { - List *pcols, *icols; - int plen, ilen; - int keep = TRUE; + List *pcols, + *icols; + int plen, + ilen; + int keep = TRUE; index = lfirst(dlist); pcols = pkey->indexParams; @@ -962,10 +975,10 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt) keep = FALSE; while ((pcols != NIL) && (icols != NIL)) { - IndexElem *pcol = lfirst(pcols); - IndexElem *icol = lfirst(icols); - char *pname = pcol->name; - char *iname = icol->name; + IndexElem *pcol = lfirst(pcols); + IndexElem *icol = lfirst(icols); + char *pname = pcol->name; + char *iname = icol->name; /* different names? then no match... */ if (strcmp(iname, pname) != 0) @@ -999,22 +1012,22 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt) extras_after = ilist; /* - * Now process the FOREIGN KEY constraints and add appropriate - * queries to the extras_after statements list. + * Now process the FOREIGN KEY constraints and add appropriate queries + * to the extras_after statements list. * */ if (fkconstraints != NIL) { - CreateTrigStmt *fk_trigger; - List *fk_attr; - List *pk_attr; - Ident *id; + CreateTrigStmt *fk_trigger; + List *fk_attr; + List *pk_attr; + Ident *id; elog(NOTICE, "CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s)"); - foreach (fkclist, fkconstraints) + foreach(fkclist, fkconstraints) { - fkconstraint = (FkConstraint *)lfirst(fkclist); + fkconstraint = (FkConstraint *) lfirst(fkclist); /* * If the constraint has no name, set it to <unnamed> @@ -1024,37 +1037,37 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt) fkconstraint->constr_name = "<unnamed>"; /* - * If the attribute list for the referenced table was - * omitted, lookup for the definition of the primary key. - * If the referenced table is this table, use the definition - * we found above, rather than looking to the system - * tables. + * If the attribute list for the referenced table was omitted, + * lookup for the definition of the primary key. If the + * referenced table is this table, use the definition we found + * above, rather than looking to the system tables. * */ if (fkconstraint->fk_attrs != NIL && fkconstraint->pk_attrs == NIL) { if (strcmp(fkconstraint->pktable_name, stmt->relname) != 0) transformFkeyGetPrimaryKey(fkconstraint); - else if (pkey != NULL) + else if (pkey != NULL) { - List *pkey_attr = pkey->indexParams; - List *attr; - IndexElem *ielem; - Ident *pkattr; + List *pkey_attr = pkey->indexParams; + List *attr; + IndexElem *ielem; + Ident *pkattr; - foreach (attr, pkey_attr) + foreach(attr, pkey_attr) { ielem = lfirst(attr); - pkattr = (Ident *)makeNode(Ident); + pkattr = (Ident *) makeNode(Ident); pkattr->name = pstrdup(ielem->name); pkattr->indirection = |